Member overloads signature not matching C++ signature
I am trying to bind a C++ class but python is reporting there is no matching signature for two of the methods which are I am trying to bind using the member function overloads macro. The class looks like so: struct path { path(); path(double line_width); void move_to(point_t point); void line_to(point_t point); void curve_to(std::array<point_t, 3>&& points) void curve_to(const std::array<point_t, 3>& points); void fill(context& ctx, bool close = true) const; void stroke(context& ctx, bool close = true) const; }; I'm not sure if this is the best way but I have made a thin wrapper around the class such that the curve_to method can be called with a tuple: struct path_wrapper : path { using path::path; void curve_to(const py::tuple& points) { path::curve_to({ py::extract<path::point_t>(points[0]), py::extract<path::point_t>(points[1]), py::extract<path::point_t>(points[2]), }); } }; The function overloads are being defined as such: BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( path_fill_overloads, fill, 1, 2 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( path_stroke_overloads, stroke, 1, 2 ); I then bind the class as such: py::class_<path_wrapper>("Path") .def(py::init<double>()) .def("move_to", &path::move_to) .def("line_to", &path::line_to) .def("curve_to", &path_wrapper::curve_to) .def("fill", &path::fill, path_fill_overloads()) .def("stroke", &path::stroke, path_stroke_overloads()); I am binding the other classes named throughout this process, but I have omitted their actual class_ calls from this message. When I make a call to the methods in python I recieve the following error: Traceback (most recent call last): File "/home/james/projects/imgen/patterns/triangles.py", line 46, in draw path.stroke(context) Boost.Python.ArgumentError: Python argument types in Path.stroke(Path, Context) did not match C++ signature: stroke(path {lvalue}, context {lvalue}) stroke(path {lvalue}, context {lvalue}, bool) I am really confused as the signatures appear to match. I suspect I've broken the converters with my wrapper class but I am unsure how to fix it. Thank you.
On 30/07/15 12:53 PM, James Maddison wrote:
I am trying to bind a C++ class but python is reporting there is no matching signature for two of the methods which are I am trying to bind using the member function overloads macro.
The class looks like so:
struct path { path(); path(double line_width);
void move_to(point_t point); void line_to(point_t point); void curve_to(std::array<point_t, 3>&& points) void curve_to(const std::array<point_t, 3>& points); void fill(context& ctx, bool close = true) const; void stroke(context& ctx, bool close = true) const; };
I'm not sure if this is the best way but I have made a thin wrapper around the class such that the curve_to method can be called with a tuple:
struct path_wrapper : path { using path::path;
void curve_to(const py::tuple& points) { path::curve_to({ py::extract<path::point_t>(points[0]), py::extract<path::point_t>(points[1]), py::extract<path::point_t>(points[2]), }); } };
I think this could be simplified a bit: You don't need an entire new type to wrap a single member function. Just use a free (non-member) function definition with an additional first argument standing for "this": void curve_to(path &p, py::tuple const &points) { ... } and then use "curve_to" instead of "&path_wrapper::curve_to" when binding it.
The function overloads are being defined as such:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( path_fill_overloads, fill, 1, 2 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( path_stroke_overloads, stroke, 1, 2 );
I then bind the class as such:
py::class_<path_wrapper>("Path") .def(py::init<double>()) .def("move_to", &path::move_to) .def("line_to", &path::line_to) .def("curve_to", &path_wrapper::curve_to) .def("fill", &path::fill, path_fill_overloads()) .def("stroke", &path::stroke, path_stroke_overloads());
I am binding the other classes named throughout this process, but I have omitted their actual class_ calls from this message.
When I make a call to the methods in python I recieve the following error:
Traceback (most recent call last): File "/home/james/projects/imgen/patterns/triangles.py", line 46, in draw path.stroke(context) Boost.Python.ArgumentError: Python argument types in Path.stroke(Path, Context) did not match C++ signature: stroke(path {lvalue}, context {lvalue}) stroke(path {lvalue}, context {lvalue}, bool)
I am really confused as the signatures appear to match. I suspect I've broken the converters with my wrapper class but I am unsure how to fix it.
I suspect the problem is that you "context" argument is a non-const reference. If it were const, the binding would work. If it has to be non-const, you need to supply a call-policy. (Unfortunately I'm not sure how to do that with the BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS macro. But given that you only have two overloads, perhaps you can avoid the macro alltogether, just to get this working. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...
participants (2)
-
James Maddison -
Stefan Seefeld