[C++-sig] Re: call_method

David Abrahams dave at boost-consulting.com
Tue Nov 12 19:46:23 CET 2002

"Peter Dimov" <pdimov at mmltd.net> writes:

>> I'd like to explore a few refinements with you. For example, it may
>> be possible to get real shared_ptr interoperability by deriving
>> py_counted_base from counted_base. Maybe we should ask Peter to
>> weigh in on this. Peter, Brett's code is attached to this page:
>> http://aspn.activestate.com/ASPN/Mail/Message/1430235
> I don't really understand what the code is about ;-) 

Here's the quick skinny: 

- Boost.Python allows you to specify how Python objects will hold the
  C++ objects they wrap. You can specify that they be held by
  shared_ptr<T> (or any other smart pointer), in which case the
  library will generate converters to/from Python for
  shared_ptr<T>. The to_python converters will simply build a new
  Python object around the shared_ptr<>.

- If you have virtual functions you want to ``override in Python'',
  you actually have to hold the T object with a derived class U which
  overrides the virtual functions to dispatch back to Python. In this
  case, class U naturally has to have access to the Python object
  (that's the pyobj_ member you see in Brett's code).

- You can further specify that your C++ object is held by
  shared_ptr<U>, which is what Brett is doing. That allows you to hold
  a U object for dispatching, yet still pass shared_ptrs around in
  your C++ code.

There are several problems with the above arrangement, but the most
important one is that if you keep the shared_ptr<U> alive longer than
its corresponding Python object, calls to the Python-overridable
virtual functions will crash, because they'll try to call through an
invalid pointer. That's what Brett is trying to address with his crazy

> but I'm leaning towards moving counted_base back to boost::detail
> and removing the intrusive counting "feature" of shared_ptr.
> The interoperability/shared_from_this problems have alternate solutions as
> described in the techniques "document".

Hmm. I guess that rules out that option.

> I'm not sure whether this helps or not, but it's also possible to have a
> shared_ptr to PyObject, by using Py_DECREF as the deleter (also described in
> the attached file).

Now /that's/ starting to sound intriguing.  I wonder if it's possible
to derive our U class from boost::python::objects::instance<>, and
automatically generate shared_ptr<> converters for it.

Maybe the whole idea of holding a shared_ptr<U> is bogus from the get-go.

                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

More information about the Cplusplus-sig mailing list