[C++-sig] More pyplusplus custom stuff

Niall Douglas s_sourceforge at nedprod.com
Thu Jun 15 13:40:37 CEST 2006


The good news is I now have a set of fully working bindings, or at 
least to the stage of where TnFOX was at the v0.85 release. The next 
problem is the orphaned child problem.

TnFOX's GUI objects, much like most C++ GUI toolkits, manage their 
own children. If you delete the parent, it deletes all its children. 
Needless to say, this is a problem for Python.

The solution is to upcall any child deletions so BPL can unhook the 
relevent python object from its C++ sibling. This is done by 
replacing the virtual functions:
   virtual void *getPythonObject() const;
   virtual void decouplePythonObject() const;

Therefore, we need to do the following:

For every class in the FX namespace which has FXObject as a base 
class, insert into EVERY constructor of the wrapper class the 
following code:

FXPython::int_pythonObjectCreated((int_decouplingFunctor=Generic::Bind
ObjN(*this, &"+wrapper_name+"::decouplePythonObject)));

Into private member variables of the wrapper class:

Generic::BoundFunctorV *int_decouplingFunctor;

Into every destructor of the wrapper class:

~"+wrapper_name+"() {
    FXPython::int_pythonObjectDeleted(int_decouplingFunctor);
    using namespace boost::python;
    using namespace std;
    PyObject *py_self=get_owner(this);
    // We must be careful not to reinvoke object destruction!
    py_self->ob_refcnt=1<<16;
    {
        object me(boost::python::handle<>(borrowed(py_self)));
        auto_ptr<"+wrapper_name+"> 
&autoptr=extract<auto_ptr<"+wrapper_name+"> &>(me);
        autoptr.release();
    }
    py_self->ob_refcnt=0
}

Into every body of the wrapper class:

virtual void *getPythonObject() const {
    return (void *) get_owner(this);
}

virtual void decouplePythonObject() const {
    using namespace boost::python;
    using namespace std;
    object me(boost::python::handle<>(borrowed(py_self)));
    auto_ptr<"+wrapper_name+"> 
&autoptr=extract<auto_ptr<"+wrapper_name+"> &>(me);
    autoptr.reset(0);
}


So, how does one achieve this then?

Cheers,
Niall






More information about the Cplusplus-sig mailing list