Boost converter for passing std::vector object by reference into a function??

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Boost converter for passing std::vector object by reference into a function??

DeVico, Mike

Hello,

 

I would like to wrap a class that looks like below (taken from an example I found on another site)

 

#include <boost/python.hpp>

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include <boost/python/suite/indexing/map_indexing_suite.hpp>

 

typedef std::vector<std::string> MyList;

class MyClass {

public:

  MyList myFuncGet()

  {

     return MyList();

  }

  void myFuncSet(MyList& list)

  {

    list.push_back("Hello");

  }

  //       stuff

};

 

BOOST_PYTHON_MODULE(MyModule)

{

    class_<MyList>("MyList")

        .def(vector_indexing_suite<MyList>() );

 

    class_<MyClass>("MyClass")

        .def("myFuncGet", &MyClass::myFuncGet)

        .def("myFuncSet", &MyClass::myFuncSet)

        ;

}

 

However, this is what I get when I try to use it from python:

 

Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.

>>> from MyModule import *

>>> mc = MyClass()

>>> p = []

>>> mc.myFuncSet(p)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

Boost.Python.ArgumentError: Python argument types in

    MyClass.myFuncSet(MyClass, list)

did not match C++ signature:

    myFuncSet(MyClass {lvalue}, std::vector<std::string, std::allocator<std::string> > {lvalue})

>>> 

 

I know I’m missing a converter function, but I’m new to boost and I don’t know what the converter

should  look like in this case.

 

I’ve found lots of working examples of how to return a vector, but I want to be able to pass the vector

into the function by reference and modify it.

 

I would really appreciate it if someone could complete the example by adding the necessary converter

code.

 

Thanks in advance.

--Mike

 


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost converter for passing std::vector object by reference into a function??

Jim Bosch-3
Your Boost.Python usage is fine.  It's the Python code that inherently
won't work:

 >> from MyModule import *
 >> mc = MyClass()
 >> p = []
 >> mc.myFuncSet(p)

Here, 'p' doesn't actually have a std::vector in it - it's a regular
Python list, so Boost.Python can't get a std::vector reference out of it.

Instead you can do:

 >> from MyModule import *
 >> mc = MyClass()
 >> p = MyList()
 >> mc.myFuncSet(p)

One could imagine writing a fancy converter that would allow the first
form by making a temporary std::vector, passing that to the C++
function, and then copying the elements in the vector back into the
Python list.  But that's potentially a very expensive sequence of
operations, and it's actually impossible to do that through a registered
converter in Boost.Python.  If you really want that Python syntax to
work, you'll have to write a C++ function that takes a
boost::python::list argument and calls the actual C++ function that
operates on std::vector.

Jim



On 01/21/2012 11:40 AM, DeVico, Mike wrote:

> Hello,
>
> I would like to wrap a class that looks like below (taken from an
> example I found on another site)
>
> #include <boost/python.hpp>
>
> #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
>
> #include <boost/python/suite/indexing/map_indexing_suite.hpp>
>
> typedef std::vector<std::string> MyList;
>
> class MyClass {
>
> public:
>
> MyList myFuncGet()
>
> {
>
> return MyList();
>
> }
>
> void myFuncSet(MyList& list)
>
> {
>
> list.push_back("Hello");
>
> }
>
> // stuff
>
> };
>
> BOOST_PYTHON_MODULE(MyModule)
>
> {
>
> class_<MyList>("MyList")
>
> .def(vector_indexing_suite<MyList>() );
>
> class_<MyClass>("MyClass")
>
> .def("myFuncGet", &MyClass::myFuncGet)
>
> .def("myFuncSet", &MyClass::myFuncSet)
>
> ;
>
> }
>
> However, this is what I get when I try to use it from python:
>
> Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit
> (AMD64)] on win32
>
> Type "help", "copyright", "credits" or "license" for more information.
>
>> >> from MyModule import *
>
>> >> mc = MyClass()
>
>> >> p = []
>
>> >> mc.myFuncSet(p)
>
> Traceback (most recent call last):
>
> File "<stdin>", line 1, in <module>
>
> Boost.Python.ArgumentError: Python argument types in
>
> MyClass.myFuncSet(MyClass, list)
>
> did not match C++ signature:
>
> myFuncSet(MyClass {lvalue}, std::vector<std::string,
> std::allocator<std::string> > {lvalue})
>
>> >>
>
> I know I’m missing a converter function, but I’m new to boost and I
> don’t know what the converter
>
> should look like in this case.
>
> I’ve found lots of working examples of how to return a vector, but I
> want to be able to pass the vector
>
> into the function by reference and modify it.
>
> I would really appreciate it if someone could complete the example by
> adding the necessary converter
>
> code.
>
> Thanks in advance.
>
> --Mike
>
>
>
> _______________________________________________
> Cplusplus-sig mailing list
> [hidden email]
> http://mail.python.org/mailman/listinfo/cplusplus-sig

_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost converter for passing std::vector object by reference into a function??

Václav Šmilauer

> One could imagine writing a fancy converter that would allow the first
> form by making a temporary std::vector, passing that to the C++
> function, and then copying the elements in the vector back into the
> Python list.  But that's potentially a very expensive sequence of
> operations, and it's actually impossible to do that through a registered
> converter in Boost.Python.

In some cases, such a converter makes sense, I wrote one (see
http://bazaar.launchpad.net/~eudoxos/+junk/tr2/view/head:/py/wrapper/customConverters.cpp#L142,
then its specializations for various types below). Where
std::vector<containedType> arg is expected, it will check whether the python
object is a sequence and then convert is to the c++ vector. Of course the
objects are being copied, not referenced, unless those objects are shared_ptr's,
in which case you get reference semantics you asked for.

Cheers, vaclav


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig