jbublitz at nwinternet.com
Tue Mar 22 20:34:10 GMT 2005
On Tuesday 22 March 2005 10:04, James Emerton wrote:
> On 22-Mar-05, at 12:23 AM, Jim Bublitz wrote:
> > It seems to me Python is taking care of all of the ref counting in
> > this case -
> > there might be pathological cases where either the C++ instance of the
> > template type or the Python instance get orphaned (no corresponding
> > object on
> > "the other side"). Most PyKDE programs don't use these types very much
> > explicitly (although the little testing I've done hasn't shown any
> > problems
> > yet).
> > Allocating new objects in each conversion function seems to bypass the
> > C++ ref
> > counting feature. There's a new C++ object created each time, but I
> > don't
> > think that makes a lot of difference. The multiple references (to
> > Python
> > objects) on the Python side will be managed by Python
> It appears that when passing Python instances back into C++ you are
> creating a second, unrelated smart pointer. Unless KSharedPtr is
> maintaining a mapping of C++ pointers, the pointer that gets passed in
> is getting an extra reference added to it that will never go away.
> When the pointer is passed back out of Python, you area creating an
> unassociated smart pointer that will deallocate the contained pointer
> when it goes out of scope, potentially leaving a dangling pointer.
Yeah - I forgot about that part (or ignorant of it - not sure which). The
problem is that incrementing the ref count of the original pointer (sipCpp)
has the same result, and the underlying object doesn't have a copy
constructor (I believe boost works that way too).
In the PyKDE case that isn't a big problem, since the code that uses smart
pointers isn't used often from Python. Probably will fix it eventually.
> My current approach is to create a small inline class in the
> %TypeHeaderCode and use SIP to wrap the inline class. This works
> wonderfully, and doesn't require any especially wacky code. =)
> Problem is, I also have places where I would like to reimplement an
> interface in Python and pass an instance back into C++ as a smart
> pointer. The inline wrapper class defeats this, of course.
> I am considering some sort of hack involving a %MappedType and a map<
> T*, boost::shared_ptr<T> > When I convert a C++ smart pointer into a
> Python type, I stick the row pointer and its corresponding smart
> pointer into a map. This holds a reference and protects the pointer.
> I also add some %MethodCode to the destructor that pulls the element
> out of the map, rather than deleting the pointer directly. The theory
> sounds pretty good, I hope it holds up in practice.
It seems like you should be able to subclass the shared ptr and bind the
subclass instead, overload the C++ dtor to Py_DECREF the corresponding Python
object (need to keep a ptr to it) and overload __del__ to decrement the ref
count of the C++ object.
More information about the PyQt