[C++-sig] class callback

Leo Yee surffirst at yahoo.com
Sun Jan 25 09:27:10 CET 2004


Hi,

I am coding c++ object which gives callback functions to python. I
encountered these problem that a c++ object destruction method won't be
called if a python class holds the c++ object that has a callback function
of this python class.

Let's look the code.

using namespace boost::python;

struct cHolder
{
 cHolder() {}
 ~cHolder()
 {
    // we can't reach here
 }

 void SetCallback( const object &o )
 {
  m_o = o;
 }

 void OnCallback(void)
 {
  if( m_o )
   m_o();
 }

 object m_o;
};


BOOST_PYTHON_MODULE( hello )
{
 class_< cHolder >( "cHolder" )
  .def( "SetCallback", cHolder::SetCallback )
  .def( "OnCallback", cHolder::OnCallback );
}


The python code looks like this:

from hello import *


class cA:
 def __init__(self):
  self._holder = cHolder()
  self._holder.SetCallback( self.callback )


 def callback( self ) :
  print 'callback'


a = cA()
a._holder.OnCallback()


I also tried to manuaully use python weakref functions to help me solving
this problem but I found that the weak reference released just as I called
the 'setcallback' function.

The weak reference code looked like this:

struct cHolder
{
 cHolder() { m_weakRef = NULL; }
 ~cHolder()
 {
    Py_XDECREF( m_weakRef );

 }

 void SetCallback( const object &o, const object &free )
 {
  m_weakRef = PyWeakref_NewRef( o.ptr(), free.ptr() );
    // the pyobject was just freed as this function had been finished
  }

 void OnCallback(void)
 {
  if( m_weakRef )
  {
   object o(borrowed(PyWeakref_GetObject( m_weakRef )));
   if( o )
    o();    // We can't reach here because o is always None
  }
 }

 PyObject *m_weakRef;
};


Does anybody know how I can solve this problem?
Thanks in advance.

Leo Yee







More information about the Cplusplus-sig mailing list