On Tuesday 22 March 2005 10:04, James Emerton wrote: > On 22-Mar-05, at 12:23 AM, Jim Bublitz wrote: > <snip> > > > 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. Jim _______________________________________________ PyKDE mailing list [email protected] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
