Reputation: 99
I am trying to modify a numpy string array from c++ with pybind11. The code i am using has the following structure:
py::array_t<py::str> process_array(py::array_t<py::str> input);
PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
m.def("process_array", process_array);
}
py::array_t<py::str> process_array(py::array_t<py::str> input) {
auto buf = input.request();
cout << &buf;
return input;
}
The problem i face is this error message:
pybind11/numpy.h:1114:19: error: static assertion failed: Attempt to use a non-POD or unimplemented POD type as a numpy dtype static_assert(is_pod_struct::value, "Attempt to use a non-POD or unimplemented POD type as a numpy dtype");
Not sure whats the catch. In python you can create numpy string arrays so what am i doing wrong? Thanks.
Upvotes: 1
Views: 3071
Reputation: 176
Fixed length strings are supported in pybind11 (tested on v2.2.3, CentOS7, python3.6.5) by using the pybind11::array_t< std::array<char, N> >
or char[N]
type. Likely you'll want to pad out the string with null values just in case, as the standard pitfalls of C-style strings apply (e.g. N-1 useable characters). I prefer working with std::array
as it doesn't decay to a char*
without calling .data()
making your intentions clearer to other readers.
So some psuedocode would look like this for a vector of 16 byte strings:
using np_str_t = std::array<char, 16>;
pybind11::array_t<np_str_t> cstring_array(vector.size());
np_str_t* array_of_cstr_ptr = reinterpret_cast<np_str_t*>(cstring_array.request().ptr);
for(const auto & s : vector)
{
std::strncpy(array_of_cstr_ptr->data(), s.data(), array_of_cstr_ptr->size());
array_of_cstr_ptr++;
}
return cstring_array; //numpy array back to python code
And then in python:
array([b'ABC', b'XYZ'], dtype='|S16')
Upvotes: 3