Boost python包装了一个虚方法 [英] Boost python wrapping a virtual method

查看:116
本文介绍了Boost python包装了一个虚方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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);
};


解决方案


  1. 在虚函数上,你引用的是包装虚函数,可以在python中进一步覆盖 - 即在从c ++类派生的python类中。逻辑是这样的,c ++只处理c ++中的虚拟分辨率;如果它落在包装器类(你的python类从中导出), this-> get_override(..)将进一步看看python类是否覆盖该特定函数。



    不清楚这是否真的是你需要的(即从c ++类派生python类)。


  2. 此外,我不明白你的函数采用什么类型的数据。你能给一个更具体的例子吗?如果你有数据要在c ++类中迭代,定义特殊的python函数 __ iter __ ,它将返回一个代理迭代器对象(你在c ++中定义了迭代器类, wrap it in python以及);这个代理迭代器必须保持内部迭代状态并定义 __ iter __ (返回self),下一个并在结束时提高StopIteraton。这是python迭代协议和所有通常的结构( for 等)将自动工作。 (请参阅这里 a>,迭代器类此处


  3. (备注)不要通过向量< int> 作为参数,避免使用 const vector< int>& 复制。

    $ b

    I'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,
    Babak

    Edit:
    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);
    };
    

    解决方案

    1. 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.

    2. 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)

    3. (Remark) don't pass vector<int> as argument, avoid copying with const vector<int>&. Converters for vector<int> from python (if you define them) will work just fine.

    这篇关于Boost python包装了一个虚方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆