Re: [pygccxml-development] Function adaptors
Brought to you by:
mbaas,
roman_yakovenko
|
From: Berserker <ber...@ho...> - 2009-08-24 09:26:09
|
> 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 :)
_________________________________________________________________
Porta Hotmail in vacanza. Leggi la posta dal cellulare!
http://new.windowslivemobile.msn.com/IT-IT/windows-live-hotmail/default.aspx |