I have two virtual classes I would like to wrap in boost python, I want to be able to write Python class that extends them. The thing is, one of the classes has a method that return a reference of the other class, and I can't figure how to do.
Here is a simplified version of code of class to be wrapped.
class Foo
{
public:
virtual ~Foo() {}
virtual int a() = 0;
};
class Bar
{
public:
virtual ~Bar() {}
virtual Foo const& b() = 0;
};
So I started wrapping about this way.
class FooWrap : public Foo, public wrapper<Foo>
{
public:
int a()
{
return this->get_override("a")();
}
};
class BarWrap : public Bar, public wrapper<Bar>
{
public:
Foo const& b()
{
return this->get_override("b")();
}
};
BOOST_PYTHON_MODULE(foobar)
{
class_<FooWrap, boost::noncopyable>("Foo")
.def("a", pure_virtual(&Foo::a))
;
class_<BarWrap, boost::noncopyable>("Bar")
.def("b", pure_virtual(&Bar::b))
;
}
And I get a compile error about "cannot instantiate abstract class [...] pure virtual function was not defined" "see declaration of 'foo::a'"
I've been able to compile and run your code after I added call policy for Bar::b function:
BOOST_PYTHON_MODULE(foobar)
{
class_<FooWrap, boost::noncopyable>("Foo")
.def("a", pure_virtual(&Foo::a));
class_<BarWrap, boost::noncopyable>("Bar")
.def("b", pure_virtual(&Bar::b),
return_internal_reference<>());
}
Basically, it's just means that lifetime of returned reference from Bar::b should be dependent on lifetime of Bar instance. You can read about call policies in boost docs.
What compiler and boost version are you using? I've got the following descriptive error with boost 1.46.0 and gcc 4.6.1:
error: no match for call to ‘(const boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<const Foo&>) (const Foo&)’
The following code compiles for me. Inside your python Bar subclass you should be able to return a Foo instance from the b method.
#include <boost/python.hpp>
class Foo
{
public:
virtual ~Foo() {}
virtual int a() = 0;
};
class Bar
{
public:
virtual ~Bar() {}
virtual Foo const& b() = 0;
};
class FooWrap : public Foo, public boost::python::wrapper<Foo>
{
public:
int a()
{
return this->get_override("a")();
}
};
class BarWrap : public Bar, public boost::python::wrapper<Bar>
{
public:
Foo const& b()
{
return this->get_override("b")();
}
};
BOOST_PYTHON_MODULE(foobar)
{
boost::python::class_<FooWrap, boost::noncopyable>("Foo")
.def("a", boost::python::pure_virtual(&Foo::a)) ;
boost::python::class_<BarWrap, boost::noncopyable>("Bar")
.def("b", boost::python::pure_virtual(&Bar::b), boost::python::return_internal_reference<>());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With