Hi Tiago,

For ElementWrap::get_float, try:
float get_float() { return this->get_override("get_float")(); }

Binding to Python of that function should then be:
.def("get_float", pure_virtual(&Element::get_float))

See also: http://www.boost.org/doc/libs/1_57_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions

With regards,

    Paul

P.S. Unrelated to your question: Try to use boost::shared_ptr instead of auto_ptr (it's deprecated). Regrettably, you can't use std::shared_ptr, since Boost Python doesn't support it.

On 08/01/15 18:42, Tiago Coutinho wrote:
Hello,

My problem is the following:

I am trying to bind a third party C++ library to python using
boost-python.
This library has a class Element and a class Owner (the later takes
ownership
of an Element object).

To make things interesting, Element defines a pure virtual method
"get_float".
The Element should be sub-classed in python. Here is a simplified
version of the
library:

// m1.hpp
---------------------------------------------------------------------
// m1.hpp

class Element {
public:
     int get_int() { return -1; }
     virtual float get_float() = 0;
};

class Owner {
     Element *m_element;

public:

     Owner(): m_element(NULL) {}
     ~Owner() { delete m_element; }
void set_element(Element* e) {
            delete m_element;
         m_element = e;
     };

     Element* get_element() { return m_element; }
};


and here is how I am binding to python:

// m1_py.cpp
----------------------------------------------------------------

class ElementWrap : public Element,
                    public wrapper<Element>
{
public:
     PyObject* self;

     ElementWrap(PyObject* self_): Element(), self(self_)
     { Py_INCREF(self); }
~ElementWrap() { Py_DECREF(self); } virtual float get_float() { return call_method<float>(self,
"get_float"); }

};

void set_element(Owner& owner, auto_ptr<Element> e) {
     owner.set_element(e.get());
     e.release();
}

BOOST_PYTHON_MODULE(m1) {
class_<Element, auto_ptr<ElementWrap>,
boost::noncopyable>("Element", init<>())
        .def("get_int", &Element::get_int)
        .def("get_float", &Element::get_float)
        ;
     register_ptr_to_python<auto_ptr<Element> >();
     implicitly_convertible<auto_ptr<ElementWrap>, auto_ptr<Element> >();


     class_<Owner>("Owner", init<>())
        .def("set_element", &set_element)
        .def("get_element", &Owner::get_element, return_internal_reference<>())
     ;
}

... but when I use it like this:

# m2.py
-----------------------------------------------------------------------

import m1

class SubElement(m1.Element):

     def get_float(self):
         return 4.5678 + self.get_int()

element = SubElement()
owner = m1.Owner()
owner.set_element(element)
element = owner.get_element()

# ops!
print (element.get_float())


I get an exception in the last line:
Traceback (most recent call last):
   File "m2.py", line 16, in <module>
     print (element.get_float())
   File "m2.py", line 8, in get_float
     return 1.0 + self.get_int()
Boost.Python.ArgumentError: Python argument types in
     Element.get_int(SubElement)
did not match C++ signature:
     get_int(Element {lvalue})

It seems that when I passed ownership to python I lost the ability to
call
a method from the base class.

Can anyone help me?

Thanks in advance

Cheers
Tiago


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
https://mail.python.org/mailman/listinfo/cplusplus-sig

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
https://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to