Finally I'm able to use std::vector in python using the [] operator. The trick is to simple provide a container in the boost C++ wrapper which handles the internal vector stuff:
#include <boost/python.hpp> #include <vector> class world { std::vector<double> myvec; void add(double n) { this->myvec.push_back(n); } std::vector<double> show() { return this->myvec; } }; BOOST_PYTHON_MODULE(hello) { class_<std::vector<double> >("double_vector") .def(vector_indexing_suite<std::vector<double> >()) ; class_<World>("World") .def("show", &World::show) .def("add", &World::add) ; }
The other challenge is: Howto translate python lists into std::vectors? I tried to add a c++ class expecting a std::vector as parameter and added the corresponding wrapper code:
#include <boost/python.hpp> #include <vector> class world { std::vector<double> myvec; void add(double n) { this->myvec.push_back(n); } void massadd(std::vector<double> ns) { // Append ns to this->myvec } std::vector<double> show() { return this->myvec; } }; BOOST_PYTHON_MODULE(hello) { class_<std::vector<double> >("double_vector") .def(vector_indexing_suite<std::vector<double> >()) ; class_<World>("World") .def("show", &World::show) .def("add", &World::add) .def("massadd", &World::massadd) ; }
But if doing so, I end up with the following Boost.Python.ArgumentError:
>>> w.massadd([2.0,3.0]) Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in World.massadd(World, list) did not match C++ signature: massadd(World {lvalue}, std::vector<double, std::allocator<double> >)
Can anybody tell me how I can access python lists within my c++ function?
Thanks, Daniel
To make your C++ method accept Python lists you should use boost::python::list
void massadd(boost::python::list& ns) { for (int i = 0; i < len(ns); ++i) { add(boost::python::extract<double>(ns[i])); } }
Here's what I use:
#include <boost/python/stl_iterator.hpp> namespace py = boost::python; template< typename T > inline std::vector< T > to_std_vector( const py::object& iterable ) { return std::vector< T >( py::stl_input_iterator< T >( iterable ), py::stl_input_iterator< T >( ) ); }
Should you find the input type (py::object) too liberal, feel free to specify stricter types (py::list in your case).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With