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 |