Python in C ++: from Deriv, to Base, to Deriv again

I use Boost.Python to expose my C ++ code in Python. I ran into difficulties associated with the fact that an object was transferred from one language to another several times. Here is what I want to do:

C ++ code

class Base { public: void baseTest() { std::cout << "Base::basetest()"; } }; class Deriv : public Base { public: void derivTest() { std::cout << "Deriv::derivTest()"; } }; void call(Base& b, boost::python::object func) { func(b); } BOOST_PYTHON_MODULE(event) { using namespace boost; using namespace boost::python; class_<Base>("Base") .def("baseTest", &Base::baseTest) ; class_<Deriv, bases<Base>>("Deriv") .def("derivTest", &Deriv::derivTest) ; def("call", call); } 

Python code

 from event import * def callback(deriv): deriv.baseTest() # works fine deriv.derivTest() # crash! def run(): d = Deriv() call(d, callback) 

What i want to do

  • C ++: calls the run() function defined in Python. (No problem here)

  • Python: run() creates a new Deriv object; it passes it and the object to the callback function, back to C ++, through the call function. (Also good)

  • C ++: call() takes a Deriv object as Base& . It passes the basic Python callback reference received by the second parameter.

  • Python: callback gets Base object from C ++. However, he expects it to be Deriv : if I call derivTest() , the program will derivTest() . However, if I call baseTest() , it does not crash.

How to make a callback not emergency?

+4
source share
1 answer

Thanks for the comments, I found a solution to this. This is actually quite simple, you just need to wrap the Base object in shared_ptr instead of passing it by reference, for example:

 void call(boost::shared_ptr<Base> b, boost::python::object func) { func(b); } 

But be careful. I tried using std :: shared_ptr, which comes with Visual C ++ 2010 Express (header "memory"), and this caused a crash. I had to use boost :: shared_ptr to make it work. (I am using version 1.46.1 of Boost.)

+1
source

All Articles