[C++-sig] boost-python: Passing an object held in a boost::shared_ptr from C++ to python to C++

Philip Dunstan phil at philipdunstan.com
Fri Aug 31 03:00:24 CEST 2012


Hi

I have some code that creates an object in a shared_ptr in C++. The object
is then used within python and passed from Python to another 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<X> into a python object.
Then when it goes back into C++ it is converted from the python object into
a new shared_ptr<X>, 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. I have attached
the full reproducible to this email. In this example an object is initially
held in a shared_ptr named s_iniital. 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());



thanks,
Phil
--
Philip Dunstan
phil at philipdunstan.com
www.philipdunstan.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20120831/eff1300d/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.cpp
Type: text/x-c++src
Size: 1862 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20120831/eff1300d/attachment.cpp>


More information about the Cplusplus-sig mailing list