Hi,
I have an issue with binding a function with an std::vector<std::vector<double>> argument.
It doesn't seem the conversion is automatically handled.
here is the error:
TypeError: function(): incompatible function arguments. The following argument types are supported:
1. (self: libcmas.City, arg0: std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, arg1: unicode) -> int
Invoked with: <libcmas.City object at 0x7fa11f6e7730>, [], 'home'
import libcmas as cmas
city = cmas.create(filename)
locations=[ ]
homes = city.function(locations, "home")
class City
{
public:
static City* Create(const std::string& file);
virtual ~City()=default;
virtual int function(std::vector<std::vector<double>>& locations, const std::string& type) = 0;
protected:
City()=default;
};
class PyCity : public City
{
public:
int function(std::vector<std::vector<double>>& locations, const std::string& type) override
{ PYBIND11_OVERLOAD_PURE(int, City, function, locations, type); }
};
PYBIND11_MODULE(libcmas, m)
{
py::class_<City, PyCity> city(m, "City");
city
.def(py::init<>())
.def("function", &City::function);
m.def("create", &City::Create);
}
The example code is incomplete (doesn't compile/run). For automatic conversion of STL containers make sure to #include <pybind11/stl.h>. Also, be aware of this FAQ entry. If that doesn't solve the issue, please post a complete code example.
Adding #include <pybind11/stl.h> solved the error.
However, the referenced argument std::vector<std::vector<double>>& locations is empty on the python side. I have searched the doc and apparently this is due to the fact that pyBind11 is performing a copy even on references. So, I made the type opaque with:
PYBIND11_MAKE_OPAQUE(std::vector<std::vector<double>>);
But the error reappears. Do I have to create a corresponding class_ declaration to associate the opaque type with a name in Python ?
Thx.
Yes, but there's a convenient py::bind_vector function which does most of the binding automatically.
Thanks. So, do I have to declare the locations python variable with the type specified in the py::bind_vector function ? Because it doesn't accept python a list
Yes: locations = MyVector([]) and then it can be passed to functions and mutated if passed by non-const reference. The docs are a bit incomplete here. This should be explained better in STL bindings section.
WORKS!! I love pybind11 !
Most helpful comment
Yes:
locations = MyVector([])and then it can be passed to functions and mutated if passed by non-constreference. The docs are a bit incomplete here. This should be explained better in STL bindings section.