Working with pointer arrays in pybind11
Pybind11 provides convient interface for C++ API. This header-only library is lightweight, easy to build, and include in a CMake project. In this post, I'm going to tackle a specific problem of working with pointer arrays in your C++ API.
Pybind11 provides a convenient interface for C++ API. This header-only library is lightweight, easy to build, and include in a CMake project. In this post, I'm going to tackle a specific problem of working with pointer arrays in your C++ API.
To get started with Pybind11, check our getting started guide
The problem of working with pointers arises from the non-bound size constraints of a pointer type. For example, consider the following function declaration
void process(double *data);
It is impossible for pybind11 to tell whether the input pointer should be a pointer to an array or a scalar.
A simple workaround for this is to implement a wrapper around the Python API call for the process function and declare the data parameter as std::vector, which tells pybind11 to expect a Python array as input.
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
class Example {
public:
Example() = {}
void process(double *data, int len) {
for (int i = 0; i < len; i++) {
data[i] *= 2;
}
}
};
namespace py = pybind11;
PYBIND11_MODULE(pyexample, m) {
py::class_<Example>(m, "Example")
.def(py::init<>())
.def("process", [](Example &m, std::vector<double> data) {
m.process(data.data(), data.size());
return data;
});
}
Note that our intention is not to make changes to the C++ API, and thus, we pass a pointer to the memory space of std::vector as the first parameter and size as the second. It is left to the user to make sure that sufficient space is allocated.