如何使用boost-python包装返回引用的虚类方法
我有两个虚拟类想要用boost python来封装,我希望能写一个Python类来扩展它们。问题是,其中一个类有一个方法返回另一个类的引用,我不知道该怎么做。
这是要封装的类的简化代码。
class Foo
{
public:
virtual ~Foo() {}
virtual int a() = 0;
};
class Bar
{
public:
virtual ~Bar() {}
virtual Foo const& b() = 0;
};
所以我开始尝试这样封装。
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))
;
}
结果我遇到了一个编译错误,提示“无法实例化抽象类[...],纯虚函数没有定义”,并且提到“查看'foo::a'的声明”。
2 个回答
3
下面的代码在我这边可以正常编译。在你的 Python Bar 子类里面,你应该能够从 b 方法返回一个 Foo 实例。
#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<>());
}
4
我在你的代码中添加了对Bar::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),
return_internal_reference<>());
}
简单来说,这意味着从Bar::b
返回的引用的生命周期应该依赖于Bar
实例的生命周期。你可以在boost文档中了解更多关于调用策略的信息。
你使用的编译器和boost版本是什么?我在使用boost 1.46.0和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&)’