Ref/unref with python

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Ref/unref with python

Paul Melis-2
Hello,

Does the C++ refcount support in python work correctly or am I not using
it as I should?

I have a c++ class Referenced that has two method ref() and unref()
which increment/decrement the refcount of the class. I use the two lines
below in my interface file (which is attached),

  %feature("ref")         Referenced      "$this->ref();"
  %feature("unref")       Referenced      "$this->unref();"

but when I run swig I don't see any call to unref() back in the
generated wrapper. The ref() function _is_ used for generating a new
instance of the class, though. Testing the code as a python module got
me curious as objects of class Referenced report when their refcount
changes and I never saw any decrement of the refcount, even when python
quits.

This is with swig 1.3.27 under linux, gcc 3.3.5, python 2.4.2

Regards,
Paul




 

-------------------------------------------------------
Paul Melis

VR Specialist,
Center for High-Performance Computing & Visualization,
University of Groningen,
The Netherlands

E: [hidden email]
W: http://www.rug.nl/rc/hpcv/index
-------------------------------------------------------


all:
        swig -c++ -python ref.i
        g++ -c -fPIC ref_wrap.cxx -I/usr/include/python2.4
        g++ -o _ref.so -shared -fPIC ref_wrap.o -L/usr/lib -lpython2.4



%module ref;

%{

template <class T>
class ref_ptr
{
public:
    ref_ptr(T *p): ptr(p) { if (ptr) ptr->ref(); }
    ~ref_ptr() { if (ptr) ptr->unref(); }
   
    T *get() { return ptr; }
   
    ref_ptr& operator=(T *p) { T *tmp = ptr; ptr = p; if (p) p->ref(); if (tmp) tmp->unref(); }
   
protected:
    T  *ptr;
};

//
// Referenced
//          

class Referenced
{
public:
        Referenced(int myid): id(myid), count(0), child1(NULL), child2(NULL) {}
       
        void ref() { count++; fprintf(stderr, "ref(%d), count now %d\n", id, count); }
        void unref() { count--; fprintf(stderr, "unref(%d), count now %d\n", id, count);
                       if (count == 0) { fprintf(stderr, "  deleting myself!\n"); delete this; } }                          
                       
        void setChild1(Referenced *r) { child1 = r; }
        void setChild2(Referenced *r) { child2 = r; }
        int getCount() const { return count; }
                       
protected:
    int id;
        int count;
        ref_ptr<Referenced> child1;
        ref_ptr<Referenced> child2;
};

%}

%feature("ref") Referenced "$this->ref();"
%feature("unref") Referenced "$this->unref();"

%nodefault Referenced;

class Referenced
{
public:
        Referenced(int myid);
        //void ref();
        //void unref();
        void setChild1(Referenced *r);
        void setChild2(Referenced *r);
        int getCount() const;
};



import ref

class C:

        def __init__(self):
                print "py: instance of C created"
               
        def __del__(self):
                print "py: instance of C deleted, __del__ called"
               
c = C()

#print "py: Creating instance of Referenced()"
#r = ref.Referenced(123)
#print "py: Referenced refcount = %d" % r.getCount()
#r.unref()

print "py: Creating instance of Referenced()"
q = ref.Referenced(456)
q = None