Thread: [pygccxml-development] Wrapping virtual functions only
Brought to you by:
mbaas,
roman_yakovenko
From: Kevin A. <kev...@gm...> - 2009-03-09 19:06:04
|
Hi there, Roman et al, First of all, thanks for the lovely tool. I've created many python wrappers, with varying degrees of automation, and it looks like PY++ is what I should have been using all along. I've been getting some behaviour I don't understand with the include and exclude methods in PY++. I am trying to create a wrapper for Qt 4.5. Qt has a nice reflection API with allows creating a very minimal generic wrapper that will work for most things -- invoking methods, getting and setting properties. The one thing you can't do is override virtual methods in python and have them get called from C++. To remedy that, the wrappings will only wrap virtual methods on classes derived from QObject. (Objects not derived from QObject don't support the Qt reflection methods and so have to be conventionally wrapped). I'm testing with the following classes: *class A { public: void g() { printf("A::g()\n"); } virtual void foo() = 0; }; class B : public A { virtual void foo() { printf("B:foo()\n"); } }; void free_func(A *a) { a->foo(); } * When I do this: *virtual_funcs = mb.member_functions(function=**lambda decl:decl.virtuality=='**virtual').include() * Py++ adds the non-virtual function g as well: *struct A_wrapper : A, bp::wrapper< A > { A_wrapper() : A() , bp::wrapper< A >(){ // null constructor } virtual void foo( ){ bp::override func_foo = this->get_override( "foo" ); func_foo( ); } }; BOOST_PYTHON_MODULE(test_lib){ bp::class_< A_wrapper, boost::noncopyable >( "A" ) .def( "foo" , bp::pure_virtual( (void ( ::A::* )( ) )(&::A::foo) ) ) .def( "g" , (void ( ::A::* )( ) )( &::A::g ) ); bp::class_< B, bp::bases< A > >( "B" ); { //::free_func typedef void ( *free_func_function_type )( ::A * ); bp::def( "free_func" , free_func_function_type( &::free_func ) , ( bp::arg("a") ) ); } } * If I do this: *mb.member_functions(function=lambda decl:decl.virtuality == "virtual").include() mb.member_functions(function=lambda decl:decl.virtuality != "virtual").exclude() * It doesn't add any member functions at all: *BOOST_PYTHON_MODULE(test_lib){ bp::class_< A, boost::noncopyable >( "A", bp::no_init ); bp::class_< B, bp::bases< A > >( "B" ); { //::free_func typedef void ( *free_func_function_type )( ::A * ); bp::def( "free_func" , free_func_function_type( &::free_func ) , ( bp::arg("a") ) ); } } * Many apologies if I doing something really stupid. Just in case, here's the whole py++ file: * import os from pyplusplus import module_builder #Creating an instance of class that will help you to expose your declarations mb = module_builder.module_builder_t( [r"C:/kevin/source/tests/py++_tests/test_lib/test_classes.h"] , gccxml_path=r"C:/Program Files/gccxml 0.9/bin/gccxml.exe" , working_directory=r"C:/kevin/source/tests/py++_tests/test_lib" , include_paths=[] , define_symbols=[] ) mb.member_functions(function=lambda decl:decl.virtuality == "virtual").include() mb.member_functions(function=lambda decl:decl.virtuality != "virtual").exclude() #Creating code creator. After this step you should not modify/customize declarations. mb.build_code_creator( module_name='test_lib' ) #Writing code to file. mb.write_module( './test_lib_bindings.cpp' ) * Many thanks, Kevin Atkinson |
From: Roman Y. <rom...@gm...> - 2009-03-09 20:12:44
|
On Mon, Mar 9, 2009 at 9:05 PM, Kevin Atkinson <kev...@gm...> wrote: > Hi there, Roman et al, Good evening. > First of all, thanks for the lovely tool. I've created many python > wrappers, with varying degrees of automation, and it looks like PY++ is what > I should have been using all along. Thank you! > I've been getting some behaviour I don't understand with the include and > exclude methods in PY++. I am trying to create a wrapper for Qt 4.5. Qt > has a nice reflection API with allows creating a very minimal generic > wrapper that will work for most things -- invoking methods, getting and > setting properties. The one thing you can't do is override virtual methods > in python and have them get called from C++. > > To remedy that, the wrappings will only wrap virtual methods on classes > derived from QObject. (Objects not derived from QObject don't support the > Qt reflection methods and so have to be conventionally wrapped). > > I'm testing with the following classes: > > class A > { > public: > void g() { printf("A::g()\n"); } > virtual void foo() = 0; > }; > > class B : public A > { > virtual void foo() { printf("B:foo()\n"); } > }; > > void free_func(A *a) > { > a->foo(); > } Let me to summarize what we have here: class A has two *public* functions: g - regular function ( virtuality == "not virtual" ) foo - pure virtual function ( virtuality == "pure virtual" ) class B has single *private* virtual function "foo" > When I do this: > > virtual_funcs = mb.member_functions(function=lambda > decl:decl.virtuality=='virtual').include() You can print the result of the statement. The only function you will see is: B::foo > Py++ adds the non-virtual function g as well: > ... By default, Py++ exports all "declarations" from the directory, where the source file is. It is explained here: http://www.language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization > If I do this: > > mb.member_functions(function=lambda decl:decl.virtuality == "virtual").include() So, you select private B::foo function and include it. Py++ will not expose it, because it is private and not pure virtual. > mb.member_functions(function=lambda decl:decl.virtuality != "virtual").exclude() Here, you select A::foo and A::g and exclude them > It doesn't add any member functions at all: I hope, now it is clear why. What you really want is to write: mb.member_functions(function=lambda decl:decl.virtuality == "not virtual").exclude() > Many apologies if I doing something really stupid. No need. You provided very detailed description and even me it took some time to understand what was going on. > Just in case, here's the whole py++ file: > ... I hope, it was clear. If not come back. I will be glad to see Qt exposed to Python using Boost Python and Py++. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |