[C++-sig] shared_ptr<> to Boost.Python wrapped object going out of scope early?

Christopher Wicklein chrisw at wicklein.org
Mon Jun 16 17:43:00 CEST 2008

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:

class Watcher(Observer):
     def __init__(self):

     def onModify(self, record):
         print record

database = Database()
watcher = Watcher()
database.watch(some_key, watcher)

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  
seems 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:

class_<ObserverWrap, boost::noncopyable>("Observer")
     .def("onModify", pure_virtual(&Observer::onModify))

Here is the wrapper class:

struct ObserverWrap : Observer, wrapper<Observer>
     onModify(Record record) { this->get_override("onModify")(record); }

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?

Christopher Wicklein <chrisw at wicklein.org>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20080616/b447a252/attachment.htm>

More information about the Cplusplus-sig mailing list