> Hi. I started to work on this and it seems I am missing something.
> Can you post a small and complete example:
> * C++ code original
> * Boost.Python code
> * Python code, which derives from the C++ class

Sure, here it is :)

C++ code:

> class Foo
> {
> public:
>     Foo() { }
>     virtual ~Foo() { }
>
> public:
>     virtual void virtual_public()
>     {
>         std::cout << "Foo::virtual_public" << std::endl;
>     }
>
> protected:
>     virtual void virtual_protected()
>     {
>         std::cout << "Foo::virtual_protected" << std::endl;
>     }
> };

Boost.Python generated code (without "embedding" changes):

> struct Foo_wrapper : ::Foo, ::boost::python::wrapper< ::Foo > {
>
>     Foo_wrapper(::Foo const & arg )
>     : ::Foo( arg )
>       , ::boost::python::wrapper< ::Foo >(){
>         // copy constructor       
>     }
>
>     Foo_wrapper( )
>     : ::Foo( )
>       , ::boost::python::wrapper< ::Foo >(){
>         // null constructor
>     }
>
>     virtual void virtual_protected(  ){
>         if( ::boost::python::override func_virtual_protected = this->get_override( "virtual_protected" ) )
>             func_virtual_protected(  );
>         else
>             this->::Foo::virtual_protected(  );
>     }
>
>     virtual void virtual_public(  ) {
>         if( ::boost::python::override func_virtual_public = this->get_override( "virtual_public" ) )
>             func_virtual_public(  );
>         else
>             this->::Foo::virtual_public(  );
>     }
>        
>     void default_virtual_public(  ) {
>         ::Foo::virtual_public( );
>     }
>
> };
>
> void register_Foo_class(){
>
>     ::boost::python::class_< Foo_wrapper >( "Foo", ::boost::python::init< >() )   
>         .def(
>             "virtual_protected"
>             , (void ( Foo_wrapper::* )(  ) )(&Foo_wrapper::virtual_protected) )   
>         .def(
>             "virtual_public"
>             , (void ( ::Foo::* )(  ) )(&::Foo::virtual_public)
>             , (void ( Foo_wrapper::* )(  ) )(&Foo_wrapper::default_virtual_public) );
>
> }

Python code (the "Foo" class is exported into a module called "osiris"):

> import osiris
>
> class PyFoo(osiris.Foo):
>     def test_public(self):
>         print 'PyFoo::test_public'
>         self.virtual_public()
>                                
>     def virtual_public(self):
>         print 'PyFoo::virtual_public'
>         osiris.Foo.virtual_public(self)
>        
>     def test_protected(self):
>         print 'PyFoo::test_protected'
>         self.virtual_protected()
>                                
>     def virtual_protected(self):
>         print 'PyFoo::virtual_protected'
>         osiris.Foo.virtual_protected(self)
>
> foo = PyFoo()
> foo.test_public()
> foo.test_protected()

"foo.test_public()" works as expected becase PyFoo.virtual_public invokes
the base method on Foo_wrapper::default_virtual_public, instead
"foo.test_protected()" causes an infinite loop because it invokes PyFoo.virtual_protected
which invokes Foo_wrapper::virtual_protected (which invokes PyFoo.virtual_protected and so on...).
As I proposed before, I think that it is necessary to generate a
"Foo_wrapper::default_virtual_protected" function in the same way of
"Foo_wrapper::default_virtual_public" and to change the "exposition" part in this way:

> void register_Foo_class(){
>
>     ::boost::python::class_< Foo_wrapper >( "Foo", ::boost::python::init< >() )   
>         .def(
>             "virtual_protected"
>             , (void ( Foo_wrapper::* )(  ) )(&Foo_wrapper::default_virtual_protected))
>         .def(
>             "virtual_public"
>             , (void ( Foo_wrapper::* )(  ) )(&Foo_wrapper::default_virtual_public) );
>
> }

Hope it helps :)


Crea l'Avatar con la tua faccia. Personalizza il tuo Messenger!