[C++-sig] PyObject * self member in class wrappers.

David Abrahams dave at boost-consulting.com
Thu Jan 9 22:46:49 CET 2003


David Sankel <camio at yahoo.com> writes:

> When a python class is being inherited from a c++
> class, one must write a c++ wrapper around the c++
> class.
>
> This wrapper must have a pointer to a PyObject called
> self.
>
> I was wondering, what exactly is this PyObject?

Its the Python object which contains the C++ object instance.

> Say I have the following scenario:
>
> class Cloneable
> {
> public:
>   virtual Cloneable * Clone()=0;
> };
>
> class PythonCloneable
> {
> public:
>   PyObject * self;
>   PythonCloneable( PyObject * self_ ) : self(self_) {}
>
>   Cloneable * Clone()
>   {
>      PythonCloneable * theCopy;
>      //... What goes here?

ordinarily,
       return call_method<Cloneable*>(self, "Clone");

>      return theCopy;
>   }
> };
>
> I would like Clone to return a copy (not instance) of
> the original.  This way, both the clone and the
> original could be modified independently.  How would I
> manipulate the self member to do this?

You wouldn't.  This is one of those interfaces which can't be wrapped
as is (not a Boost.Python limitation; it's the nature of the interface
and Python's reference-counting GC).  The problem is that there's no
way to keep the Python object that results from calling Clone on a
derived class alive.  If you try the code above, and call Clone on
such a class, you'll get a nice, descriptive exception in python that
says your result pointer would be dangling.  

An interface that you *can* wrap reliably would have you returning
boost::shared_ptr<Cloneable> from your Clone() function, which is a
much better design from the C++ side anyway.

[Actually, there's a way to hack your way around it: make all derived
Clone functions stick the result instance in a global list, so they
live forever]

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