[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