Boost python wrapping a virtual method

2019-02-16 01:42发布

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条回答
Viruses.
2楼-- · 2019-02-16 01:49
  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.

查看更多
登录 后发表回答