[C++-sig] More pyplusplus custom stuff

Roman Yakovenko roman.yakovenko at gmail.com
Thu Jun 15 20:30:14 CEST 2006


On 6/15/06, Niall Douglas <s_sourceforge at nedprod.com> wrote:
> 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.

Congratulation !!!

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

Niall, there is pretty simple solution, but I am not sure I want it
within pyplusplus.
May be as temporal patch, but I will remove it after we will implement
"call wrapper
policies" ( http://language-binding.net/pyplusplus/peps/call_wrapper_policies.html
)

Description: ( solution for destructor )

cls = mb.class_( 'X' )
cls.add_wrapper_code( destructor declaration and definition )

You can do it with your version of pyplusplus

Description for constructor:

1. add pyplusplus.decl_wrappers.constructor_t new property
    body ( string )

2.  add code that insert this member variable into generated code in
next classes:
     pyplusplus.code_creators.
         constructor_wrapper_t
         special_constructor_wrapper_t
         trivial_constructor_wrapper_t

3. initialize the body property
    > 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:

    mb = module_builder_t( ... )
    FX = mb.namespace( 'FX' )
    FXObject = FX.class_( 'FXObject' )
    classes = FX.classes(
          lambda decl: pygccxml.declarations.is_based_and_derived(
FXObject, decl ) )
    for cls in classes:
        cls.constructors().body = ...
        cls.add_wrapper_code( ... )

Pretty simple and readable, right :-)?

Enjoy

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/



More information about the Cplusplus-sig mailing list