Boost python包装了一个虚方法 [英] Boost python wrapping a virtual method
问题描述
我使用boost python来创建对c ++库的绑定。在这个库中的许多类有虚拟方法接受iterator / const_iterator类型作为参数。我不是特别想暴露这些类型,但宁愿创建一些包装器接受适当的容器的虚拟方法。我的问题是,在默认实现函数中执行这个包装是否安全?
class Test
{
public:
Test
virtual〜Test();
virtual void iterate(std :: vector< int> :: iterator it);
};
然后用wrapper类封装默认值。
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中的位置。我想包装这个功能,使其界面更加pythonic,但我不知道正确的方法来做这个,而kepping它的虚拟。
class FieldMapping
{
public:
...
virtual void voxelToWorld(std :: vector< V3d> :: const_iterator vsP,
std :: vector< V3d> :: const_iterator end,
std :: vector< V3d> :: iterator wsP);
};
-
在虚函数上,你引用的是包装虚函数,可以在python中进一步覆盖 - 即在从c ++类派生的python类中。逻辑是这样的,c ++只处理c ++中的虚拟分辨率;如果它落在包装器类(你的python类从中导出),
this-> get_override(..)
将进一步看看python类是否覆盖该特定函数。
不清楚这是否真的是你需要的(即从c ++类派生python类)。
-
此外,我不明白你的函数采用什么类型的数据。你能给一个更具体的例子吗?如果你有数据要在c ++类中迭代,定义特殊的python函数
__ iter __
,它将返回一个代理迭代器对象(你在c ++中定义了迭代器类, wrap it in python以及);这个代理迭代器必须保持内部迭代状态并定义__ iter __
(返回self),下一个
并在结束时提高StopIteraton。这是python迭代协议和所有通常的结构(for
等)将自动工作。 (请参阅这里 a>,迭代器类此处) -
(备注)不要通过
向量< int>
作为参数,避免使用const vector< int>&
复制。
$ bI'm using boost python to create a binding to a c++ library. A number of classes in this library have virtual methods which accept iterator/const_iterator types as arguments. I don't particularly want to expose these types but would prefer to create some wrappers around these virtual methods that accept the appropriate container instead. My question is, is it safe to do this wrapping in the 'default implementation' function ?
e.g.
class Test { public: Test(); virtual ~Test(); virtual void iterate(std::vector<int>::iterator it); };
then with the wrapper class wrap the default..
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()); } };
and setting up the binding with...
boost::python::class_< Test_wrapper >("Test") .def("iterate" ,(void ( Test_wrapper::* )(std::vector<int>))(&Test_wrapper::default_iterate));
I'm unsure about this because the tutorial says that two functions need to be passed to 'def' but just passing one seems to work.. (http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions)
Any advice with this would be greatly appreciated.
thanks in advance,
BabakEdit:
More specifically I'm trying to bind a class which contains a method 'voxelToWorld'. This method transforms the positions in wsP based on points in vsP/end. I would like to wrap this function up so that its interface is more 'pythonic', however I'm not sure of the correct way to do this while kepping it virtual as well.class FieldMapping { public: ... virtual void voxelToWorld(std::vector<V3d>::const_iterator vsP, std::vector<V3d>::const_iterator end, std::vector<V3d>::iterator wsP); };
解决方案Documentation on virtual functions you reference is related to wrapping virtual functions which can be further overridden in python -- i.e. in python classes deriving from the c++ class. The logic is such that c++ only handles virtual resolution in c++; if it lands on the wrapper class (from which your python classes derive),
this->get_override(..)
will further look if the python class overrides that particular function.It is not clear whether this is really what you need (i.e. deriving python classes from c++ classes). If you only want to expose regular c++ virtual functions, virtual resolution is handled automatically.
Further, I don't understand what kind of data your functions take. Can you give a more specific example? If you have data you want to iterate over in the c++ class already, define special python functions
__iter__
, which will return an proxy iterator object (you define the iterator class in c++ and wrap it in python as well); this proxy iterator must hold internally iteration state and define__iter__
(returning self),next
(returning next container item), and raise StopIteraton at the end. Such is the python iteration protocol and all usual constructs (for
etc) will work automagically. (see e.g. here, iterator class here for an example)(Remark) don't pass
vector<int>
as argument, avoid copying withconst vector<int>&
. Converters forvector<int>
from python (if you define them) will work just fine.
这篇关于Boost python包装了一个虚方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!