[C++-sig] Passing Python classes derived from C++ back into C++
Paul Scruby
paul at gingernut.tv
Tue Jul 7 12:54:56 CEST 2009
Hiya,
I'm trying to pass a C++ class that I've extended in Python to a C++
function. I found an example of how to do this in David Abrahams article on
Building Hybrid Systems with Boost Python.
http://www.boostpro.com/writing/bpl.html#virtual-functions
However, I've not managed to get this example to compile:
#include <string>
#include <boost/python.hpp>
using namespace boost::python;
class Base
{
public:
virtual int f(std::string x) { return 42; }
virtual ~Base() {}
};
int calls_f(Base & b, std::string x) { return b.f(x); }
struct BaseWrap : Base
{
BaseWrap(PyObject * self_) : self(self_) {}
PyObject * self;
int f_default(std::string x) { return this->Base::f(x); }
int f(std::string x) { return call_method<int>(self, "f", x); }
};
BOOST_PYTHON_MODULE(mytest)
{
def("calls_f", calls_f);
class_<Base, BaseWrap>("Base")
.def("f", &Base::f, &BaseWrap::f_default);
}
_________________
from mytest import *
class Derived(Base):
def f(self, s):
return len(s)
calls_f(Base(), 'foo')
calls_f(Derived(), 'forty-two')
With Boost 1.38 and Visual Studio 8 compiler I get the error:
boost_1_38\boost\python\object\make_instance.hpp(68) : see reference to
function template instantiation
'boost::python::objects::value_holder_back_reference<Value,Held>::value_holder_back_reference<boost::reference_wrapper<T>>(PyObject
*,A0)' being compiled
with
[
Value=Base,
Held=BaseWrap,
T=const Base,
A0=boost::reference_wrapper<const Base>
]
With Boost 1.63 and Sun C++ 5.9 compiler I get the error:
boost-1_36/boost/python/object/class_metadata.hpp", line 232:
Error: Overloading ambiguity between "static
boost::python::objects::class_metadata<Base, BaseWrap,
boost::python::detail::not_specified,
boost::python::detail::not_specified>::maybe_register_pointer_to_python(void*,
void*, void*)"
and "static boost::python::objects::class_metadata<Base, BaseWrap,
boost::python::detail::not_specified,
boost::python::detail::not_specified>::maybe_register_pointer_to_python(void*,
void*, mpl_::bool_<1>*)".
I also tried extending the boost::python::wrapper<T> using get_override()
instead of call_method<T>(), but as it can not be constructed with a
PyObject * so the C++ base class can't be extracted from a Python
derivation.
Has anyone managed to get this working? Any help will be gratefully
received.
Cheers,
Paul
More information about the Cplusplus-sig
mailing list