From: David P. <dpi...@me...> - 2008-04-07 15:32:26
|
> I took another swipe at adding reference counting to our C++/Python > interface and hit another wall. I have reference counted pointers in C+ > + and use the %ref and %unref directives to try to add reference > counting to python. The problem is that, storing pointers to objects > which are returned from C++ code do not cause the reference count to > be incremented. Example code: > > # this increments > m= Lib.Container() > p= Lib.Object() > index= m.store_object(p) > p=None > #the reference count is not incremented here > p2=m.get_object(index) > # nor is it decremented here > p2= None > > This is with swig 1.33. There is something in the change notes for > 1.34 about adding support for shared_ptr, but I couldn't find > documentation online. Are there other changes to improve reference > counting? I'm a bit surprised, as I thought python ref-counting worked properly ;) I have the same problem in C#. My solution, like Josh's, is to use "out" typemaps in place of %feature("ref"): %define %counted_obj(TYPE) // The 'ref' and 'unref' features enable reference counting on 'new' and // 'delete' only (in C#, delete is called during garbage collection.) // These are nice features because they apply to a whole type hierarchy. // Unfortunately, they are not enough. The refcount must be incremented // whenever a function returns TYPE*, so we use the 'out' typemap to // accomplish that. Since the 'out' typemap applies to the 'new' operator, // we cannot use 'ref' to add a reference at the same time, for it would // cause a second increment. Unfortunately, typemaps do not apply to // entire hierarchies, so %counted_obj must be used on EVERY class in a // hierarchy, not just the base class. %feature("ref") TYPE "// $this->AddRef();" %feature("unref") TYPE "$this->ReleaseRef();" %typemap(out, null="NULL") TYPE* %{ if ($1 != NULL) $1->AddRef(); $result = $1; %} // in the target language you must make typemaps to ensure the // "owner" flag is set. ... ... %enddef |