<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I've been having problems getting a C++ class wrapped with Boost.Python to be shared appropriately between Python and C++ library code. The Python program looks like this:<div><br></div><div><font class="Apple-style-span" face="Courier">class Watcher(Observer):</font></div><div><font class="Apple-style-span" face="Courier"> def __init__(self):</font></div><div><font class="Apple-style-span" face="Courier"> Observer.__init__(self)</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier"> def onModify(self, record):</font></div><div><font class="Apple-style-span" face="Courier"> print record</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">database = Database()</font></div><div><font class="Apple-style-span" face="Courier">watcher = Watcher()</font></div><div><span class="Apple-style-span" style="font-family: Courier; ">database.watch(some_key, watcher)</span></div><div><font class="Apple-style-span" face="Courier">cl_service_all()</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div>The basic idea is that an instance of a wrapped database record observer is created, the observer is registered with the C++ object wrapped by database via a passed shared_ptr (the second argument of database.watch) and retained by the library as a weak_ptr, and the program drops into a C-based event loop which is integrated with the C++ library providing the observer and database classes. The C++ library fails at runtime because the weak_ptr becomes invalid. It <i>seems</i> that the shared_ptr passed to database.watch isn't retained by the Python code above. To fill things out a bit, here is the Boost.Python statement used to wrap the Observer:</div><div><br></div><div><font class="Apple-style-span" face="Courier">class_<ObserverWrap, boost::noncopyable>("Observer")</font></div><div><font class="Apple-style-span" face="Courier"> .def("onModify", pure_virtual(&Observer::onModify))</font></div><div><font class="Apple-style-span" face="Courier">;</font></div><div><br></div><div>Here is the wrapper class:</div><div><br></div><div><font class="Apple-style-span" face="Courier">struct ObserverWrap : Observer, wrapper<Observer></font></div><div><font class="Apple-style-span" face="Courier">{</font></div><div><font class="Apple-style-span" face="Courier"> onModify(Record record) { this->get_override("onModify")(record); }</font></div><div><font class="Apple-style-span" face="Courier">}</font></div><div><br></div><div>Having done a little diagnostic work by printf, I believe that an instance of Oberver is created, passes as a shared_ptr to the library, and accessible to the library prior to entering the event loop. When the weak pointer which was good before entering the event loop is locked from within the event loop, the weak pointer has become invalid. I presume that what I'm trying to do (hold a wrapped object by a shared_ptr on the Python side and allow a C++ library to hold a weak_ptr to that object) isn't too strange and that there should be some idiomatic way to make this work. Is there something in particular I need to do so that the Python side doesn't drop the shared pointer, or is it clear from the code above that I have some critical misunderstanding of how to use Boost.Python?</div><div><br></div><div><div apple-content-edited="true"> <div><div>----</div><div>Christopher Wicklein <<a href="mailto:chrisw@wicklein.org">chrisw@wicklein.org</a>></div><div><br></div></div><br> </div><br></div></body></html>