Python object lifetime extension

castes:

#include <boost/python.hpp> using namespace boost; using namespace boost::python; struct Foo { virtual ~Foo() {} virtual void Print() = 0; }; struct FooWrap : Foo, wrapper<Foo> { void Print() { this->get_override("Print")(); } }; void ProcessFoo(Foo *obj) { obj->Print(); } BOOST_PYTHON_MODULE(hello_ext) { class_<FooWrap, boost::noncopyable>("Foo") .def("Print", pure_virtual(&Foo::Print)); def("ProcessFoo", &ProcessFoo); } 

python:

 import hello_ext class NewFoo(hello_ext.Foo): def Print(self): print 'Print call' hello_ext.ProcessFoo( NewFoo() ) 

Everything works fine, there is the text Print call from the ProcessFoo call. But I want to save all passed pointers to ProcessFoo as follows:

 std::vector<Foo*> data; void ProcessFoo(Foo *obj) { data.push_back(obj); obj->Print(); } 

After exiting the function, the pointer becomes invalid, and I cannot use it from the vector. What is the best way to extend the life of this pointer? Use shared pointers or tell python not to delete the object (if it deletes it?)

+4
source share
1 answer

If you want to keep this pointer, you need to increase the reference count for the base python object (PyObject). To do this, you need to implement your void ProcessFoo (Foo * obj) to get a python object instead of a C ++ object, because otherwise boost :: python will deprive the python object for you in its adaptation, and you will no longer be able to control it life time.

If you do this, you also need to do a direct conversion like C ++ (but with boost :: python this is not much of a problem).

 using namespace boost::python; std::vector< std::pair<object, Foo&> > myVec; void ProcessFoo(object o ) { Foo& x = extract<Foo&>(o); // ... do you add to container here, but remember, to add the object o // too, otherwise the refernce counter will be decremented and the object // may go away. myVec.push_back( std::make_pair( o, x ) ); } 
+2
source

All Articles