You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to enable passing of numpy.ndarray objects to functions that have std::vector (and other arithmetic types) in the signature. At the moment it seems like my type_caster is not registered. I added a breakpoint to the load method but never reached this code.
Is my caster missing something, or do I need to explicitly register it (like in boost::python), or is it conflicting with pre-existing type_casters for std::vector included with pybind11? I would like the behavior to extend the default caster for std::vector rather than override it.
I wrote a type_caster in NumpyToVector.h:
#pragma once
#include<pybind11/pybind11.h>
#include<pybind11/numpy.h>
#include<vector>namespacepy= pybind11;
namespacepybind11::detail {
template <>
classPYBIND11_EXPORT type_caster<std::vector<double>>
{
public:using T = double;
using type = std::vector<T>;
staticconstexprauto py_name = _("std_vector");
PYBIND11_TYPE_CASTER(type, py_name);
// Conversion from Python to C++boolload(handle src, bool)
{
// https://github.com/pybind/pybind11/issues/563auto buf = array::ensure(src);
if (isinstance<array_t<T>>(buf))
{
array arr = src.cast<array>(); // Convert to array// Ensure the array is 1Dif (arr.ndim() != 1)
{
returnfalse;
}
// Ensure the array contains the correct dtype (double)//if (!arr.dtype().is(dtype::of<T>()))if (!detail::npy_format_descriptor<T>::dtype().is(arr.dtype()))
{
returnfalse;
}
// Get the data pointerconstauto data_ptr = static_cast<const T *>(arr.data());
constauto size = arr.size();
// Convert to std::vector<double>
value = std::vector<T>(data_ptr, data_ptr + size);
returntrue;
}
returnfalse;
}
static handle cast(const type& src, return_value_policy /* policy */, handle /* parent */)
{
throwstd::runtime_error("Not implemented.");
};
};
I include this in one of the compilation units of "ModuleA.pyd":
#include<pybind11/pybind11.h>
#include"NumpyToVector.h"PYBIND11_MODULE(ModuleA, m)
{
// export some classes and functions, unrelated to NumpyToVector.hExport1(m);
Export2(m);
}
In a LibraryB.dll I include the header "NumpyToVector.h" and execute some Python code as follows
std::vector<double> data(100, 42.0);
///
py::object main_module = py::module::import("__main__");
py::object numpy = py::module::import("numpy");
py::object ndarray = py::module::import("ModuleA");
// Convert std::vector to numpy array directly
py::array_t<double> np_array(data.size(), data.data());
main_module.attr("x") = np_array;
py::object main_namespace = main_module.attr("__dict__");
py::object res = py::eval("2.0*x", main_namespace);
bool ok = py::isinstance<py::array_t<double>>(res); // -> is 'true'
result = res.cast<std::vector<double>>(); // throws a pybind11::cast_error
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I would like to enable passing of numpy.ndarray objects to functions that have std::vector (and other arithmetic types) in the signature. At the moment it seems like my type_caster is not registered. I added a breakpoint to the
load
method but never reached this code.Is my caster missing something, or do I need to explicitly register it (like in boost::python), or is it conflicting with pre-existing type_casters for std::vector included with pybind11? I would like the behavior to extend the default caster for std::vector rather than override it.
I wrote a type_caster in NumpyToVector.h:
I include this in one of the compilation units of "ModuleA.pyd":
In a LibraryB.dll I include the header "NumpyToVector.h" and execute some Python code as follows
Beta Was this translation helpful? Give feedback.
All reactions