Barry
Barry

Reputation: 303127

boost python raw_function method

I want to expose a class method using raw_function. Something like:

namespace py = boost::python;

class MyObject {
public:
    py::object foo(py::tuple args, py::dict kwargs) {
        // whatever
    }
};

Right now, I can use raw_function to wrap a static function that has to pull self out, so something like:

static py::object MyObject_foo(py::tuple args, py::dict kwargs) {
    MyObject& self = py::extract<MyObject&>(args[0]);

    // the docs allege that I can do args.slice(1), but that doesn't
    // compile on boost 1.55 at least, with no matching function
    // call to 'boost::python::tuple::slice(int ) const
    self.foo(py::extract<py::tuple>(args.slice(1, py::len(args))),
             kwargs);
}

py::class_<MyClass>("MyClass")
    .def("foo", py::raw_function(&MyObject_foo, 1));

That works, but is pretty verbose. I actually have several raw functions that I need wrapped and would prefer not to have to go through this intermediate step on each one of them. Is there a shorter way to wrap MyObject::foo?

Upvotes: 2

Views: 935

Answers (1)

mkeeter
mkeeter

Reputation: 73

You can skip the extra function by using a static member function, then extracting self in the same way, i.e.

namespace py = boost::python;

class MyObject {
public:
    static py::object foo(py::tuple args, py::dict kwargs)
    {
        MyObject& self = py::extract<MyObject&>(args[0]);
        // Do stuff with the self object
    }
};

py::class_<MyObject>("MyObject")
    .def("foo", py::raw_function(&MyObject::foo, 1));

It's not quite wrapping a class method directly, but it's cleaner than using an intermediate function.

Upvotes: 2

Related Questions