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