2

This is an follow up question to std::vector to boost::python::list

I tried the provided example:

// C++ code
typedef std::vector<std::string> MyList;
class MyClass {
   MyList myFuncGet();
   void myFuncSet(MyList& list)
   {
      list.push_back("Hello");
   }
};

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

using namespace boost::python;

BOOST_PYTHON_MODULE(mymodule)
{
    class_<MyList>("MyList")
        .def(vector_indexing_suite<MyList>() );

    class_<myClass>("MyClass")
        .def("myFuncGet", &MyClass::myFuncGet)
        .def("myFuncSet", &MyClass::myFuncSet)
        ;
}

But when I try to actually use it in Python I get an error (See bottom).

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 mymoduleimport *
>>> 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})

From what I've been able to gather by reading various other sites & posts, a converter is required. Can someone complete my example by adding in the necessary converter code? I'd do it myself, but I'm not familiar enough with boost to know what such a converter looks like.

Thanks in advance!

Community
  • 1
  • 1
mod
  • 21
  • 2

1 Answers1

3

I believe you can only use converters when passing the argument by value or const reference. Passing by nonconst reference requires that the type be directly exposed. This means that if you want to pass a list from python to c++, without copying the list items, you'll need to change your code to work with a boost::python::list rather than MyList, which'll be something like (untested)

void myFuncSet(boost::python::list& list)
{
   list.append("Hello");
}

The vector indexing suite adds python list like behaviour to your MyList binding, it doesn't let you pass a python list in its place.

The error you're getting in your example is because you're trying to pass a python list to a function which take a std::vector<int>. I suspect this would work

p = mc.myFuncGet()
mc.myFuncSet(p)

This is quite a helpful article on writing converters. http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/

babak
  • 774
  • 3
  • 11