Hi, > Ok lets say my BaseClass has a member function called init( vector4 ): > > class Base > { > public: > void init( vector4 &vec ) { //doWhatEver } > //a lot of other functions > }; > > Unfortunetaly i can not expose this init function directly to python so > i am writing a BaseWrapper
Why's that? Can't you expose vector4 to Python? > So when i am exposing Base and Derived like: > > > BOOST_PYTHON_MODULE( my_module ) > { > > class_<Base, BaseWrapper>( "Base", init<>() ) > .def("init", &BaseWrapper::_init) > ; > class_<Derived, bases<Base> >( "Derived", init<>() ); > } > > I want to have all functions for objects of Derived that are available > in Base. > The thing is, that e.g. ipython recognizes the functions. > So in ipython, when i have an object of type Derived with tab completion > i see the functions from Base. > But when i try to call them i always get this "signature" error. I think the problem is that the Derived class doesn't actually have any inheritance relationship with BaseWrapper, i.e. Base / \ / \ / \ BaseWrapper Derived So in an example like this // file cppcode.hpp #include <iostream> class Base { protected: int m_area; public: Base() : m_area(0) {} void init(int area) { m_area = area; } virtual void print() { std::cout << "hello Base " << m_area << std::endl; } }; class Derived : public Base { public: virtual void print() { std::cout << "hello Derived " << m_area << std::endl; } }; // only to show callback-into-python-overrides necessities void callback(Base& base) { base.print(); } // file wrap.cpp #include <boost/python.hpp> #include "cppcode.hpp" namespace bp = boost::python; class BaseWrapper : public Base, public bp::wrapper<Base> { public: void _init(int x, int y) { init(x * y); } }; BOOST_PYTHON_MODULE(cppcode) { bp::class_<BaseWrapper, boost::noncopyable>("Base") .def("init", &BaseWrapper::_init) .def("printIt", &Base::print) ; bp::class_<Derived, bp::bases<Base> >("Derived"); bp::def("callback", &callback); }; #!/apps/local/gcc/4.5.1/bin/python2.7 # file test.py import cppcode print "---> base" base = cppcode.Base() base.printIt() base.init(3, 4) base.printIt() print "---> derived" derived = cppcode.Derived() derived.printIt() derived.init(3, 4) derived.printIt() cppcode.callback(derived) class PythonDerived(cppcode.Base): def printIt(self): print "hello PythonDerived" print "---> python derived" pyderived = PythonDerived() pyderived.printIt() cppcode.callback(pyderived) I run into this error when trying to call .init() on the Derived object: $ python2.7 ./test.py ---> base hello Base 0 hello Base 12 ---> derived hello Derived 0 Traceback (most recent call last): File "./test.py", line 23, in <module> derived.init(3, 4) Boost.Python.ArgumentError: Python argument types in Base.init(Derived, int, int) did not match C++ signature: init(BaseWrapper {lvalue}, int, int) Which makes sense since Derived does not inherit from BaseWrapper. > So i do not know how to use those callback approach you suggested. > Especially if you are using function overloading. And additionally, this > would mean, that i have to write such a callback function for each > function in my base class as a global function. Never mind the callback, I might have just confused you. The callback is only for showing that you'd need a Wrapper class if you want to inherit in Python and be able to call back from C++ into Python and actually call methods overridden in Python. > One thing i have to mention is, that it is perfectly working if i omit > the BaseWrapper class. So if the functions of Base can be exposed > without using a wrapper class: > [...] > ...works. But unfortunately not with the BaseWrapper Class :-( Because now you don't have the problem that Derived has no inheritance relationship with BaseWrapper. Maybe you can just use a free function: // file wrap.cpp #include <boost/python.hpp> #include "cppcode.hpp" namespace bp = boost::python; void _init(Base& base, int x, int y) { base.init(x * y); } BOOST_PYTHON_MODULE(cppcode) { bp::class_<Base>("Base") .def("init", &_init) .def("printIt", &Base::print) ; bp::class_<Derived, bp::bases<Base> >("Derived"); bp::def("callback", &callback); }; # file test.py import os import sys import cppcode print "---> base" base = cppcode.Base() base.printIt() base.init(3, 4) base.printIt() print "---> derived" derived = cppcode.Derived() derived.printIt() derived.init(3, 4) derived.printIt() cppcode.callback(derived) class PythonDerived(cppcode.Base): def printIt(self): print "hello PythonDerived" print "---> python derived" pyderived = PythonDerived() pyderived.printIt() # to make this invoke PythonDerived.printIt() you need a wrapper class cppcode.callback(pyderived) ===> $ python2.7 ./test.py ---> base hello Base 0 hello Base 12 ---> derived hello Derived 0 hello Derived 12 hello Derived 12 ---> python derived hello PythonDerived hello Base 0 >>> Holger Landesbank Baden-Wuerttemberg Anstalt des oeffentlichen Rechts Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz HRA 12704 Amtsgericht Stuttgart _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig