On 16/12/14 11:13 PM, Peter LaDow wrote: > I'm embedding Python (using boost::python) into an application plugin > that uses callbacks. Essentially, I want to do something like: > > In Python (say test.py): > > def do_something(): > ... > > register_callback(do_something) > > And on the C++ side I register the register_callback() function: > > void register_callback(boost::python::object& o) > { > // Access some persistent state information > }
You defined 'do_something' as a callback, and registered it so it could be called from C++, yes ? Then, in your implementation of 'register_callback', 'o' is actually a reference to your callback function. Do you want to access the persistent state while registering the callback, or from within the callback ? Or am I misreading the code above ? Stefan > BOOST_PYTHON_MODULE(foo) > { > boost::python::def("register_callback", register_callback); > } > > void library_entry() > { > PyImport_AppendInittab("foo", initfoo); > > PyInitialize(); > > // Create some persistent state information > > boost::python::exec_file("test.py", ...); > } > > The issue here is that I need to create the Python context and store > things away in an opaque pointer I return to the application. And when > Python calls back into the C++, I need to recover that opaque value. > For example: > > Application -- (calls) --> my C++ library -- (runs) --> Python script > -- (calls) --> my C++ library > > For that last step, I need to recover some opaque data. Further, I > need that opaque data to be persistent. The calls into my C++ library > are callbacks from the application. The issue I'm having is trying to > figure out how to pass that state information to the C++ > register_callback() function. I've tried something like: > > namespace bp = boost::python; > > class state_info_t > { > }; > > void register_callback(std::shared_ptr<state_info_t>& state, bp::object& o); > { > // Access some persistent state information > } > > // Create some persistent state information > std::shared_ptr<state_info_t> state = std::make_shared<state_info_t>(); > > PyImport_AppendInittab("foo", initfoo); > > Py_Initialize(); > > std::shared_ptr<bp::object> main_module = > std::make_shared<bp::object>(bp::handle<>(bp::borrowed(PyImport_AddModule("__main__")))); > bp::object main_namespace = main_module->attr("__dict__"); > std::shared_ptr<bp::object> foo_module = > std::make_shared<bp::object>(bp::handle<>(PyImport_ImportModule("foo"))); > > main_namespace["foo"] = *foo_module; > > bp::scope foo_scope(*foo_module); > > // Both of these fail with _a lot_ of errors, most related to "no > matching function call to 'get_signature' > bp::def("register_callback", > [&](bp::object& o) { register_callback(state, o); }, > bp::arg("func")); > > bp::def("register_callback", > std::bind(register_callback, state, std::placeholders::_1), > bp::arg("func")); > > The other thought I had was to store the persistent data in the > module's dictionary. But I don't know how to recover it in the > callback. For example: > > // Create some persistent state information > std::shared_ptr<state_info_t> state = std::make_shared<state_info_t>(); > > PyImport_AppendInittab("foo", initfoo); > > Py_Initialize(); > > std::shared_ptr<bp::object> main_module = > std::make_shared<bp::object>(bp::handle<>(bp::borrowed(PyImport_AddModule("__main__")))); > bp::object main_namespace = main_module->attr("__dict__"); > std::shared_ptr<bp::object> foo_module = > std::make_shared<bp::object>(bp::handle<>(PyImport_ImportModule("foo"))); > bp::object foo_namespace = main_module->attr("__dict__"); > > main_namespace["foo"] = *foo_module; > foo_namespace["state"] = bp::handle<>(state); // Whatever the > appropriate wrapper is > > Then in C++ side of register_callback: > > void register_callback(bp::object& o) > { > // How do I extract "state" from the context? > } > > I'm not keen on this last one, since it exposes the state information > to the script. > > I don't want to make the state information global since there may be > multiple running Python instances. And regardless, with multiple > Python instances I still need a way to determine which Python instance > is running to select the appropriate state information. > > Any suggestions? > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > https://mail.python.org/mailman/listinfo/cplusplus-sig -- ...ich hab' noch einen Koffer in Berlin... _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig