I followed the test examples that I found on the web, and I am able to replicate the examples.
My issue occurs when I: 1) Write a C++ base class 2) Wrap this C++ base class in C++ 3) Inherit from this wrapped C++ class in python 4) Then try to use this python inherited class as an argument into a different C++ function expecting the C++ base class I created in step 1. I have attached the C++ and py code. My C++ code: #include <string> #include <map> #include <iterator> #include <iostream> #include <iosfwd> #include <boost/python.hpp> using namespace boost::python; namespace // unnamed { struct Base { virtual ~Base() {}; virtual int f() const = 0; }; struct BaseWrap : Base, wrapper<Base> { virtual ~BaseWrap() {} int f() const { return this->get_override("f")(); } }; void functionWithBaseArgument(Base & baseObj) { std::cout << "You have successfully called 'functionWithBaseArgument'" << std::endl; std::cout << "Value: " << baseObj.f() << std::endl; } class classWithBaseMember { public: classWithBaseMember (const Base & baseObj) : baseObj_(baseObj) {} void test() const { std::cout << "You have successfully called 'classWithBaseMember::test': " << std::endl; int d = baseObj_.f(); std::cout << "Value: " << d << std::endl; } private: const Base & baseObj_; }; class DoubleVector // empty stub class { public: DoubleVector() {} DoubleVector(int s, double v) {} ~DoubleVector() {} }; class DoubleMatrix // empty stub class { public: DoubleMatrix() {} DoubleMatrix(int nr, int nc, double v) {} ~DoubleMatrix() {} }; class MathSmoothFunction { public: MathSmoothFunction() {} virtual ~MathSmoothFunction() {} virtual double value(const DoubleVector& currentPoint) const = 0; virtual DoubleVector gradient(const DoubleVector& currentPoint) const = 0; virtual DoubleMatrix hessian(const DoubleVector& currentPoint) const { return DoubleMatrix(); } private: }; class PyWrapSmoothFunction : public MathSmoothFunction, public wrapper<MathSmoothFunction> { public: PyWrapSmoothFunction() {} virtual ~PyWrapSmoothFunction() {} virtual double value(const DoubleVector& currentPoint) const { return call<double>(this->get_override("value").ptr(),currentPoint); } virtual DoubleVector gradient(const DoubleVector& currentPoint) const { return call<DoubleVector>(this->get_override("gradient").ptr(),currentPoint); } virtual DoubleMatrix hessian(const DoubleVector& currentPoint) const { return call<DoubleMatrix>(this->get_override("hessian").ptr(),currentPoint); } private: }; class classWithBaseMember2 { public: classWithBaseMember2 (const MathSmoothFunction& baseObj) : baseObj_(baseObj) {} void test() { std::cout << "You have successfully called 'classWithBaseMember2::test': " << std::endl; //std::cout << "Value: " << value( DoubleVector(1,-5.0) ) << std::endl; } private: const MathSmoothFunction& baseObj_; }; } // end namespace unnamed void init_pyivm() { class_<DoubleVector> ("DoubleVector") .def(init<>()) .def(init<int, double>()) ; class_<DoubleMatrix> ("DoubleMatrix") .def(init<>()) .def(init<int, int, double>()) ; class_<BaseWrap, boost::noncopyable > ("Base", "Base") .def("f", pure_virtual(&Base::f)) ; class_<classWithBaseMember, boost::noncopyable> ("classWithBaseMember", "classWithBaseMember", init<const Base&>() ) .def("test", &classWithBaseMember::test) ; def("functionWithBaseArgument", functionWithBaseArgument); class_<PyWrapSmoothFunction, boost::noncopyable > ("PyWrapSmoothFunction", "PyWrapSmoothFunction") .def("value", pure_virtual(&MathSmoothFunction::value) ) .def("gradient", pure_virtual(&MathSmoothFunction::gradient) ) .def("hessian", pure_virtual(&MathSmoothFunction::hessian) ) ; class_<classWithBaseMember2, boost::noncopyable> ("classWithBaseMember2", "classWithBaseMember2", init<const MathSmoothFunction&>() ) .def("test", &classWithBaseMember2::test) ; } BOOST_PYTHON_MODULE(_testPyInheritVM) { init_pyivm(); } ------------------------------------------------------------------------------------------- My python code is: ------------------------------------------------------------------------------------------- #!/usr/bin/python # # import os, sys import math from _testPyInheritVM import * ################################################## # THIS WORKS ################################################## class Dummy: def __init__(self): pass base = Base() dummy = Dummy() class Derived(Base): def f(self): return 42 derived = Derived() derived.f() functionWithBaseArgument(derived) cwbm = classWithBaseMember(derived) cwbm.test() ################################################## # THIS DOESN'T WORK ################################################## class MyPySmoothFunction(PyWrapSmoothFunction): def __init__(self): pass def value(self, point): return 0.0 def gradient(self, point): return DoubleVector() def hessian(self, point): return DoubleMatrix() myFn = MyPySmoothFunction() myClassHasAPyWrapSmoothFn = classWithBaseMember2(myFn) ------------------------------------------------------------------------------------------- The error I get when I run this is: Traceback (most recent call last): File "testPyInheritVM.py", line 49, in <module> myClassHasAPyWrapSmoothFn = classWithBaseMember2(myFn) Boost.Python.ArgumentError: Python argument types in classWithBaseMember2.__init__(classWithBaseMember2, MyPySmoothFunction) did not match C++ signature: __init__(_object*, (anonymous namespace)::MathSmoothFunction) ------------------------------------------------------------------------------------------- I have tried various things but can't seem to get this to work. Any help would be hugely appreciated. --Liam ============================================================================================= Email transmissions can not be guaranteed to be secure or error-free, as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of email transmission. In addition, the information contained in this email message is intended only for use of the individual or entity named above. If the reader of this message is not the intended recipient, or the employee or agent responsible to deliver it to the intended recipient, you are hereby notified that any dissemination, distribution,or copying of this communication, disclosure of the parties to it, or any action taken or omitted to be taken in reliance on it, is strictly prohibited, and may be unlawful. If you are not the intended recipient please delete this email message. ==============================================================================================
#include <string> #include <map> #include <iterator> #include <iostream> #include <iosfwd> #include <boost/python.hpp> using namespace boost::python; namespace // unnamed { struct Base { virtual ~Base() {}; virtual int f() const = 0; }; struct BaseWrap : Base, wrapper<Base> { virtual ~BaseWrap() {} int f() const { return this->get_override("f")(); } }; void functionWithBaseArgument(Base & baseObj) { std::cout << "You have successfully called 'functionWithBaseArgument'" << std::endl; std::cout << "Value: " << baseObj.f() << std::endl; } class classWithBaseMember { public: classWithBaseMember (const Base & baseObj) : baseObj_(baseObj) {} void test() const { std::cout << "You have successfully called 'classWithBaseMember::test': " << std::endl; int d = baseObj_.f(); std::cout << "Value: " << d << std::endl; } private: const Base & baseObj_; }; class DoubleVector // empty stub class { public: DoubleVector() {} DoubleVector(int s, double v) {} ~DoubleVector() {} }; class DoubleMatrix // empty stub class { public: DoubleMatrix() {} DoubleMatrix(int nr, int nc, double v) {} ~DoubleMatrix() {} }; class MathSmoothFunction { public: MathSmoothFunction() {} virtual ~MathSmoothFunction() {} virtual double value(const DoubleVector& currentPoint) const = 0; virtual DoubleVector gradient(const DoubleVector& currentPoint) const = 0; virtual DoubleMatrix hessian(const DoubleVector& currentPoint) const { return DoubleMatrix(); } private: }; class PyWrapSmoothFunction : public MathSmoothFunction, public wrapper<MathSmoothFunction> { public: PyWrapSmoothFunction() {} virtual ~PyWrapSmoothFunction() {} virtual double value(const DoubleVector& currentPoint) const { return call<double>(this->get_override("value").ptr(),currentPoint); } virtual DoubleVector gradient(const DoubleVector& currentPoint) const { return call<DoubleVector>(this->get_override("gradient").ptr(),currentPoint); } virtual DoubleMatrix hessian(const DoubleVector& currentPoint) const { return call<DoubleMatrix>(this->get_override("hessian").ptr(),currentPoint); } private: }; class classWithBaseMember2 { public: classWithBaseMember2 (const MathSmoothFunction& baseObj) : baseObj_(baseObj) {} void test() { std::cout << "You have successfully called 'classWithBaseMember2::test': " << std::endl; //std::cout << "Value: " << value( DoubleVector(1,-5.0) ) << std::endl; } private: const MathSmoothFunction& baseObj_; }; } // end namespace unnamed void init_pyivm() { class_<DoubleVector> ("DoubleVector") .def(init<>()) .def(init<int, double>()) ; class_<DoubleMatrix> ("DoubleMatrix") .def(init<>()) .def(init<int, int, double>()) ; class_<BaseWrap, boost::noncopyable > ("Base", "Base") .def("f", pure_virtual(&Base::f)) ; class_<classWithBaseMember, boost::noncopyable> ("classWithBaseMember", "classWithBaseMember", init<const Base&>() ) .def("test", &classWithBaseMember::test) ; def("functionWithBaseArgument", functionWithBaseArgument); class_<PyWrapSmoothFunction, boost::noncopyable > ("PyWrapSmoothFunction", "PyWrapSmoothFunction") .def("value", pure_virtual(&MathSmoothFunction::value) ) .def("gradient", pure_virtual(&MathSmoothFunction::gradient) ) .def("hessian", pure_virtual(&MathSmoothFunction::hessian) ) ; class_<classWithBaseMember2, boost::noncopyable> ("classWithBaseMember2", "classWithBaseMember2", init<const MathSmoothFunction&>() ) .def("test", &classWithBaseMember2::test) ; } BOOST_PYTHON_MODULE(_testPyInheritVM) { init_pyivm(); }
testPyInheritVM.py
Description: testPyInheritVM.py
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig