-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embedding python in C++ Code to pass stl containers by reference #1508
Comments
For test_ref.cc, use the pybind embedded interpreter when using pybind11 modules as per the docs warning. Just replace two lines. @@ -1,4 +1,4 @@
-#include "Python.h"
+#include <pybind11/embed.h> // everything needed for embedding
#include "pybind11/pybind11.h"
#include "util.h"
@@ -100,7 +100,7 @@ void test_ref()
int main()
{
- Py_Initialize();
+ py::scoped_interpreter guard{}; // start the interpreter and keep it alive
test_ref();
return 0;
} For _c11binds.cc, you need to add two things described in the docs. Had you bound a vector of your custom class, those bindings would be visible globally by default. I also changed to the newer PYBIND11_MODULE syntax @@ -6,16 +6,21 @@
namespace py = pybind11;
+PYBIND11_MAKE_OPAQUE(std::vector<int>);
+PYBIND11_MAKE_OPAQUE(std::vector<std::string>);
+typedef std::map<std::string,double> stringdoublemap;
+PYBIND11_MAKE_OPAQUE(stringdoublemap); // because PYBIND11_MAKE_OPAQUE(std::map<std::string,double>) was not compiling for me
+
struct ABC {
int i;
int j;
};
-PYBIND11_PLUGIN(_cc11binds) {
- py::module m("_cc11binds", "C++ type bindings created by py11bind");
- py::bind_vector<std::vector<int>>(m, "IntVector");
- py::bind_vector<std::vector<std::string>>(m, "StringVector");
- py::bind_map<std::map<std::string, double>>(m, "StringDoubleMap");
+
+PYBIND11_MODULE(_cc11binds, m) {
+ m.doc() = "C++ type bindings created by py11bind";
+ py::bind_vector<std::vector<int>>(m, "IntVector", py::module_local(false));
+ py::bind_vector<std::vector<std::string>>(m, "StringVector", py::module_local(false));
+ py::bind_map<std::map<std::string, double>>(m, "StringDoubleMap", py::module_local(false));
// 'bind_map` does not create method `values`.
- return m.ptr();
} |
That's because |
But there is a test for that |
Thank you this code is working for me. I made some changes to the code where in I wanted to pass a reference struct to embedded python function. I added the following function in stl.py Now when I am trying to invoke this function in C++ It throws an error "unable to convert argument of type 'listABC*' to Python object" |
Looks like you didn't bind |
Ohhh sorry missed that line in my previous comment. Adding the full code for understanding. By the way I have removed _cc11binds dependency so that entire c++ code is in one file. What I am confused about is passing vector to python is fine. before But the moment, we pass object of type listABC as a reference to python interpreter,
I don't see any updates done by python interpreter to c++ caller i.e. it is passed by value. |
the problem is
|
I have another doubt here. I was trying to make the program multithreaded. #0 0x00007ffff7a98ce0 in _PyTrash_thread_destroy_chain () from /lib64/libpython2.7.so.1.0 Attaching the changed code. |
What if you use the pybind11 functions for GIL control? You have to be extra careful when using the embedded interpreter and treading. You can't create multiple interpreters, so you would have to create threads of Another thing I noticed when i was running your previous code, you have void test_ref()
{
py::module mod = py::module::import("stl");
testing_ref(2, mod);
} |
I think I got the problem. I was unnecessarily taking GIL lock before making the python call on the lines of boost::python. Will mark this issue as closed. Thanks for the help. |
I have a usecase where I have implemented an API in python and it needs to return struct, vector or map to C++. Could you please help me with an example how to do that. All the usecases I see in pybind is just simply python being embedded in C++ without any return value. The scenario which I need to implement is a python -> C++ interface where the C++ caller will start a session and call various python objects when it wants and then close the session. Any help would be highly appreciated.
I tried to implement the solution as given under the link (http://zpz.github.io/embedding-python-in-cpp-3) scenario 3 but that is failing for me with the error:
[root@scspa0521148001 py4cc]# ./main
=== pass as
&x
===before
cumsum
, in C++ --- [1, 3, 5]terminate called after throwing an instance of 'pybind11::cast_error'
what(): make_tuple(): unable to convert argument of type 'std::vector<int, std::allocator >*' to Python object
Aborted (core dumped)
py4cc.zip
The text was updated successfully, but these errors were encountered: