Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export std::vector

I'm writing application wiht boost.python library. I want to pass function into python which returnes std::vector. I have a little troubles:

inline std::vector<std::string> getConfigListValue(const std::string &key)
{
    return configManager().getListValue(key);
}

BOOST_PYTHON_MODULE(MyModule)
{
    bp::def("getListValue", getListValue);
}

When I call that function from python I get:

TypeError: No to_python (by-value) converter found for C++ type: std::vector<std::string, std::allocator<std::string> >

What have I missed?

like image 951
Max Frai Avatar asked Mar 15 '11 15:03

Max Frai


2 Answers

It is a bit old question, but I've found that if you explicitly require to return by value, like so:

namespace bp = boost::python

BOOST_PYTHON_MODULE(MyModule)
{
    bp::def("getListValue", getListValue,
            bp::return_value_policy<bp::return_by_value>());
}      

rather than

BOOST_PYTHON_MODULE(MyModule)
{
    bp::def("getListValue", getListValue);
}

Python does the conversion for you (I am using Python 2.7 at the time of writing this answer) and there is no need to declare/define the converter.

@Tryskele

like image 94
mgfernan Avatar answered Sep 18 '22 14:09

mgfernan


You should write a converter like this:

template<class T>
struct VecToList
{
    static PyObject* convert(const std::vector<T>& vec)
    {
        boost::python::list* l = new boost::python::list();
        for(size_t i = 0; i < vec.size(); i++) {
            l->append(vec[i]);
        }

        return l->ptr();
    }
};

And then register it in your module:

BOOST_PYTHON_MODULE(MyModule)
{
    boost::python::to_python_converter<std::vector<std::string, std::allocator<std::string> >, VecToList<std::string> >();
    boost::python::def("getListValue", getListValue);
}
like image 37
Fábio Diniz Avatar answered Sep 18 '22 14:09

Fábio Diniz