Dear Phil,

the problem you are phasing is because you use a weak pointer. I had a
very similar problem in April, you may read it up here
  http://mail.python.org/pipermail/cplusplus-sig/2012-April/016524.html
There I also tried to explain why this happens, I'm not sure if I did
a good job, just ask.

To be able to help you here, can you explain a little bit more about
your usecase?

In my case I was able to exploit that the weak_ptr that I needed to
access, was a pointer to the class itself. And I only ran into
trouble, that I wanted to call an unsafe function like your
`putSharedPtr` from python, when I extended this class from python.
Whenever I needed to use `s_copied` I call a function, say
`getPointer()`, that in pure C++ would just turn `s_copied` from
weak_ptr into shared_ptr. In python extended classes I implement
`getPointer()` not in terms of `s_copied`, but by just returning
`self`.

-Holger



On Fri, Aug 31, 2012 at 3:00 AM, Philip Dunstan <p...@philipdunstan.com> wrote:
> 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
> p...@philipdunstan.com
> www.philipdunstan.com
>
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig@python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to