I have an object that is held in a shared_ptr in C++. The object is accessed through the python bindings from within python and passed to another bound C++ function that tries to keep hold of it. It appears that when the object goes from C++ to Python it is converted from a shared_ptr into a python object. Then when it goes back into C++ it is converted from the python object into a new shared_ptr, however this shared_ptr is unrelated to the initial holding shared_ptr.
Is it possible to set up the boost-python bindings so that the conversion from python object to shared_ptr references the original shared_ptr internals?
Below is the abridged code I have used to show the problem.
In this example an object is initially held in a shared_ptr named s_inital. It is grabbed from within python through the getSharedPtr function, then pushed back into C++ through the putSharedPtr function. Inside putSharedPtr it is copied into the weak_ptr s_copied. Inspecting the pointers in the debugger shows that the shared_ptr used in putSharedPtr does not have the same reference counting internals as s_initial. The final assert will fire because the weak pointer s_copied was only related to a single strong pointer (the pointer used in putSharedPtr) and that pointer was destructed once putSharedPtr was finished.
static shared_ptr<Captured> s_initial;
static weak_ptr<Captured> s_copied;
class UseSharedPtr
{
public:
shared_ptr<Captured> getSharedPtr()
{
return s_initial;
}
void putSharedPtr(shared_ptr<Captured> ptr)
{
s_copied = ptr;
}
};
BOOST_PYTHON_MODULE(test)
{
class_<Captured, shared_ptr<Captured>, boost::noncopyable>("Captured", no_init);
class_<UseSharedPtr, boost::noncopyable>("UseSharedPtr", init<>())
.def("getSharedPtr", &UseSharedPtr::getSharedPtr)
.def("putSharedPtr", &UseSharedPtr::putSharedPtr)
;
}
s_initial = make_shared<Captured>();
const char* chunk = "\
from test import UseSharedPtr \n\
x = UseSharedPtr() \n\
ptr = x.getSharedPtr() \n\
x.putSharedPtr(ptr)\n\
del x \n\
del ptr \n\
";
object result = exec(chunk, mainNamespace, mainNamespace);
assert(s_copied.lock());
UseSharedPtr
class? Just asCaptured
is exposed now, boost::python will handle that correctly. – Tenderizeshared_ptr
as parameter to other classes. – Merell