Boost logo

Boost :

From: timfisken_at_[hidden]
Date: 2001-09-23 09:34:57


--- In boost_at_y..., "David Abrahams" <david.abrahams_at_r...> wrote:
> Yeah, you are missing something, though I have to admit it's a
subtle point.
> It took me quite a while to figure out what was going on with your
case. The
> problem is that because boost::shared_ptr<> uses a non-intrusive
reference
> count, you can't create a shared_ptr to any arbitrary object.
Boost.Python
> was designed to be able to handle objects returned from C++ held by
all
> kinds of smart pointers (e.g. std::auto_ptr). Given an arbitrary
object of
> type T, it isn't possible to safely create a shared_ptr<T>, because
the T's
> lifetime may be managed by some auto_ptr<> or even some other
shared_ptr<>.

I think I see. It did occour to me that using non-intrusive reference
counted smart pointers with the reference counted python objects
would be difficult, but when I saw the various to_python and
from_python functions for shared_ptr, I assumed Boost.Python was
doing something clever. Which it is, but unfortunately it isn't being
quite as magic as I had hoped.

Would it be possible for Boost.Python to include some kind of smart
pointer for holding objects passed from python? Or perhaps it does
already. What I mean is, a class which uses intrusive reference
counting on the PyObject of the relevant extension-class. This would
allow a C++ class to keep pointers to objects passed to it from
python.

Perhaps there is another way of accomplishing this. What I want to
implement is effectively a plugin system - the majority of my program
is in C++, with an abstract base plugin class. Then, you can create
plugins by deriving from this class in python and passing an instance
of this python class to a C++ plugin-manager, which stores them for
later use. I can't store a copy of the object without slicing, and I
can't store a raw pointer, because the python object will go out of
scope.

I can't see a way of doing this at the moment. If my understanding of
how Boost.Python works is correct, though, a python_ptr<T> as I
described it above shoudln't be too hard to produce. Something like
this:

template<class T>
class python_ptr<T>
{
  T* actual_object_;
  PyObject* python_object_;
public:
  python_ptr(PyObject* p)
  {
    actual_object_ = from_python<T*>(p);
    python_object_ = p;
    Py_XINCREF(p);
  }

  ~python_ptr()
  {
    Py_XDECREF(python_object_);
  }
};

With the relevant operator->() etc., and to_python and from_python
functions. Does this sound like something that would work? Or is
there a better way to accomplish what I want?

Thanks for your help, anyway.

-- 
Tim Fisken
223 King's College
07740 928082

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk