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 [email protected] https://mail.python.org/mailman/listinfo/cplusplus-sig
