Hello, I have C++ code with several C-style functions which look like this:
void some_function(double* array, int array_size) { do something with array }
What's the easiest way to wrap these functions? I thought about casting the Python list/numpy array directly to a an array in C++ allocated with new double[array_size] an then calling some_function but I'm
not sure how to do that.
The easiest approach is probably to bind an intermediate wrapper taking a std::vector and passing its data to the real function:
#include <pybind11/stl.h>
// ...
m.def("some_function", [](std::vector<double> array) {
return some_function(array.data(), array.size());
});
Thanks a lot, this works for me when the function is not defined in a class, however, when some_function is a member of a class, I get an error about incompatible arguments.
Here's a minimal example which reproduces the issue for me:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
class some_class {
double class_member;
};
void some_function(double* array, int array_size) {
array[0] = 2.;
}
namespace py = pybind11;
PYBIND11_MODULE(example_module, m) {
m.def("some_function", [](std::vector<double> array) {
return some_function(array.data(), array.size());
});
py::class_<some_class>(m, "some_class")
.def(py::init())
.def("some_member_function", [](std::vector<double> array) {
return 0.;
});
}
Calling the functions in python results in:
In [2]: import example_module as m
In [3]: m.some_function([0.1, 0.5])
In [4]: instance = m.some_class()
In [5]: instance.some_member_function([0.1, 0.5])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-38c8de031c83> in <module>()
----> 1 instance.some_member_function([0.1, 0.5])
TypeError: some_member_function(): incompatible function arguments. The following argument types are supported:
1. (self: List[float]) -> float
Invoked with: <example_module.some_class object at 0x1467438e0110>, [0.1, 0.5]
In [6]:
fread(ESPLout, sizeof(double), rsize * zsize, f);
I'm not very good at C++ so I might be missing something obvious.
The "something obvious" is the fact that in order to call a member function, you need a reference to 'this', so the lambda you define also needs to take a corresponding parameter:
.def("some_member_function", [](some_class& self, std::vector<double> array) {
return self.some_member_function(...);
});
Thank you so much!
Most helpful comment
The "something obvious" is the fact that in order to call a member function, you need a reference to 'this', so the lambda you define also needs to take a corresponding parameter: