newobject and feature("ref")

View: New views
5 Messages — Rating Filter:   Alert me  

newobject and feature("ref")

by tahoma :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

I tried swig 1.3.35 - 1.3.39.

Best regards,
Jan
--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01



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

test.h (844 bytes) Download Attachment
test.i (302 bytes) Download Attachment

Re: newobject and feature("ref")

by Ben Webb :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

tahoma@... wrote:

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

I believe it's intended behavior - at least, that's what I see when I
use SWIG in a similar way. After all, SWIG does not know whether your
own creator methods are returning a 'new' reference or a 'borrowed'
reference (you could have written your creator methods so that they
increased the reference count, expecting that C++ callers of these
methods decrease the refcount when they're done). In cases where you
return a borrowed reference, you could always use a typemap to get your
desired behavior, such as:

%typemap(out) TYPE * {
   if (!($owner & SWIG_POINTER_NEW)) {
     // out typemaps are also called for constructors, which already
     // use %ref to increase the reference count. So don't do it twice.
     $1->incrementReferenceCount();
   }
   %set_output(SWIG_NewPointerObj(%as_voidptr($1), $descriptor(TYPE *),
$owner | SWIG_POINTER_OWN));
}

        Ben
--
ben@...                      http://salilab.org/~ben/
"It is a capital mistake to theorize before one has data."
        - Sir Arthur Conan Doyle

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

Re: newobject and feature("ref")

by David Piepgrass :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 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

Re: newobject and feature("ref")

by tahoma :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 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").

I am quite happy with feature("ref") and it works really well with any method
returning an object of type (or derived from that) RefCountObject.

Unfortunately is does not work if a class method returns that type thats class
is *not* derived from RefCountObject. For me it looks like a bug, too. Btw, I
generate Python wrappers with that.

It seems that the class hosting the %newobject method is also taken into
account while evaluating %feature("ref") and not only the return type.

Regards,
Jan

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

Re: newobject and feature("ref")

by David Piepgrass :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> > 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").
>
> I am quite happy with feature("ref") and it works really well with any
> method
> returning an object of type (or derived from that) RefCountObject.
>
> Unfortunately is does not work if a class method returns that type thats
> class
> is *not* derived from RefCountObject. For me it looks like a bug, too.
> Btw, I
> generate Python wrappers with that.

By the way, it occurs to me %feature("ref") might work differently in Python than in C#... I remember getting that impression from something I read a long time ago on the mailing list but now I forget. I know I didn't notice the bug you describe back when I was trying out %feature("ref")... but then, I didn't use it very long since its semantics are not very useful, at least in C#.

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