[C++-sig] Member overloads signature not matching C++ signature
Stefan Seefeld
stefan at seefeld.name
Fri Jul 31 17:04:37 CEST 2015
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...
More information about the Cplusplus-sig
mailing list