> Hi all,
>
> I want to use my own reference counting when wrapping my classes. When
> using
> %feature("ref") and %newobject the reference counter will be increased
> only in
> methods of classes derived from RefCountObject. I thought the ref/unref
> feature is applied to any return type derived from RefCountObject when
> %newobject is used.
>
> A small example is given in test.h/test.i. Creator1, Creator2 and a global
> function create instances of type RefCountObject, but only the reference
> counter of instances returned by Creator2 are increased. Creator2 is the
> only
> class that also derives from RefCountObject.
>
> Is that behaviour intended or did I miss something important? I want to
> use
> tool classes that do not derive from RefCountObject but creating or
> returning
> RefCountObject's.
That sounds like a bug to me. But feature("ref") won't automatically increment the refcount on objects returned from functions other than the ref-counted class's constructor, so I do not use feature("ref") at all in my programs. I use feature("unref") but not feature("ref"). Instead, I use a set of typemaps like this:
///////////////////////////////////////////////////////////////////////////
// Reference-counting typemaps for C# via AddRef() and ReleaseRef()
//
// Adds support for reference counting the specified type, assuming that the
// type includes AddRef() and ReleaseRef() methods. Unfortunately, this must
// be applied to every class in a ref-counted class hierarchy. Also, this
// macro changes many typemaps, and it may be incompatible with other macros
// that change the same typemaps.
//
// If you use %counted_obj on a base class then you get some, but not all,
// of the ref-counting logic in derived classes. Coincidentally, the most
// common mistake I make is to use %counted_obj on the base class "B" but
// forget to use it on a derived class "D". This mistake has two
// symptoms when dealing with pointers to D objects:
// 1. If some C++ method returns a D*, SWIG doesn't increment the ref-count,
// but it doesn't decrement the ref-count when the wrapper is destroyed
// either. Bottom line: either nothing bad happens, OR you might use the
// object after it is destroyed.
// 2. If you allocate a D in C# with "new D()", AddRef() is not called, so
// the refcount is zero. When that D instance is finalized, however,
// ReleaseRef() is called. If some C++ code handles this D object, it
// may be AddRef'd, then ReleaseRef'd, causing the object to be freed
// prematurely.
%define %counted_obj(TYPE)
// The 'ref' and 'unref' features enable reference counting on 'new'
// and 'delete' only (in C#, delete is called for 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 %feature("ref") to
// add a reference at the same time, for it would cause a second
// increment. Unfortunately, typemaps do not apply to entire
// inheritance hierarchies, which is why %counted_obj must be used
// on every class in a hierarchy.
%feature("unref") TYPE "$this->ReleaseRef(); // unref"
%typemap(csin) TYPE "$csinput.Ptr"
%typemap(in) TYPE* %{ $1 = (TYPE*)$input; %}
%typemap(varin) TYPE* %{ $1 = (TYPE*)$input; %}
%typemap(memberin) TYPE* %{ $1 = (TYPE*)$input; %}
%typemap(out, null="NULL") TYPE* %{
if ($1 != NULL) $1->AddRef(); // C# side is responsible for releasing the reference
$result = $1;
%}
%typemap(csout, excode=SWIGEXCODE) TYPE* {
IntPtr cPtr = $imcall;$excode
if (cPtr == IntPtr.Zero)
return null;
return new $csclassname(cPtr, true);
}
%typemap(csvarout, excode=SWIGEXCODE2) TYPE* %{
get {
IntPtr cPtr = $imcall;$excode
if (cPtr == IntPtr.Zero)
return null;
return new $csclassname(cPtr, true);
} %}
%enddef
------------------------------------------------------------------------------
Are you an open source citizen? Join us for the Open Source Bridge conference!
Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
Need another reason to go? 24-hour hacker lounge. Register today!
http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user