Boost Python 包装虚拟方法
我正在使用boost python来创建一个与C++库的绑定。这个库里有很多类,它们有一些虚拟方法,这些方法接受迭代器/常量迭代器类型作为参数。我并不想直接暴露这些类型,而是希望围绕这些虚拟方法创建一些包装,使它们接受合适的容器作为参数。我的问题是,在“默认实现”函数中进行这样的包装是否安全?
例如:
class Test
{
public:
Test();
virtual ~Test();
virtual void iterate(std::vector<int>::iterator it);
};
然后用包装类来包装默认的...
struct Test_wrapper: Test, boost::python::wrapper<Test>
{
.....
virtual void iterate(std::vector<int>::iterator it);
void default_iterate(std::vector<int> it)
{
Test::iterate(it.begin());
}
};
并设置绑定为...
boost::python::class_< Test_wrapper >("Test")
.def("iterate" ,(void ( Test_wrapper::* )(std::vector<int>))(&Test_wrapper::default_iterate));
我对此不太确定,因为教程说需要传递两个函数给'def',但只传递一个似乎也能工作... (http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions)
对此的任何建议都将非常感激。
提前谢谢,
Babak
编辑:
更具体地说,我正在尝试绑定一个包含方法'voxelToWorld'的类。这个方法根据vsP/end中的点来转换wsP中的位置。我想把这个函数包装起来,使它的接口更“符合Python风格”,但我不确定在保持它为虚拟方法的同时,正确的做法是什么。
class FieldMapping
{
public:
...
virtual void voxelToWorld(std::vector<V3d>::const_iterator vsP,
std::vector<V3d>::const_iterator end,
std::vector<V3d>::iterator wsP);
};
1 个回答
你提到的关于虚函数的文档是关于如何在Python中包装虚函数的,这样可以在Python中进一步重写这些函数,也就是说在从C++类派生的Python类中。逻辑是这样的:C++只在C++中处理虚函数的解析;如果它到达了包装类(你的Python类是从这个类派生的),那么
this->get_override(..)
会进一步检查Python类是否重写了那个特定的函数。目前还不清楚这是否真的是你需要的(也就是说,从C++类派生Python类)。如果你只是想暴露普通的C++虚函数,虚函数的解析会自动处理。
另外,我不太明白你的函数需要什么样的数据。你能给个更具体的例子吗?如果你在C++类中已经有了想要遍历的数据,可以定义特殊的Python函数
__iter__
,这个函数会返回一个代理迭代器对象(你在C++中定义迭代器类,然后在Python中包装它);这个代理迭代器必须内部保存迭代状态,并定义__iter__
(返回自身)、next
(返回下一个容器项),并在结束时抛出StopIteration。这样的就是Python的迭代协议,所有常用的构造(比如for
等)都会自动工作。(例如,查看这里,迭代器类的例子在这里)(备注)不要将
vector<int>
作为参数传递,避免使用const vector<int>&
进行复制。如果你定义了从Python到vector<int>
的转换器,它们会正常工作。