如何通过pybind11用用户定义的structs的numpy数组调用C++API

How to call C++ API with numpy array of user defined structs via pybind11

本文关键字:structs numpy 调用 C++API 数组 定义 何通过 pybind11 用户      更新时间:2024-04-27

我浏览了文档,在互联网上搜索了很多,但找不到任何解决方案。以下是的相关代码片段

struct Ohlc {
double open, high, low, close;
int volume;
};
using array_dtype = Ohlc;
void calculate_ema_pyarray(const py::array_t<const array_dtype,
py::array::c_style | py::array::forcecast> array) {
// DO something with array
}
PYBIND11_MODULE(ema_calculator_pybind11, m) {
// optional module docstring
m.doc() = "pybind11 plugin for ema calculations";
py::class_<Ohlc>(m, "Ohlc")
.def(py::init<>())
.def_readwrite("open", &Ohlc::open)
.def_readwrite("high", &Ohlc::high)
.def_readwrite("low", &Ohlc::low)
.def_readwrite("close", &Ohlc::close);
PYBIND11_NUMPY_DTYPE(Ohlc, open, high, low, close);
m.def("calculate_ema", &calculate_ema_pyarray,
"Calculates EMA for given input");
}

以下是我在python 中使用它时遇到的错误

>>> from ema_calculator_pybind11 import *
>>> import numpy as np
>>> calculate_ema(np.array([Ohlc()]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: calculate_ema(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[ema_calculator_pybind11.Ohlc]) -> None
Invoked with: array([<ema_calculator_pybind11.Ohlc object at 0x7f926d284670>],
dtype=object)

如果我将array_dtype更改为内建类型(例如using array_dtype = double;(,或者如果我只接受Ohlc的一个对象而不是一个数组,则上述操作有效。不确定这是一个缺失的功能或bug,还是我的代码中很可能缺失了什么。请告知。

请参阅此处关于将数据分配给结构化数组的部分。您可以传递表示数据类型中每个字段值的元组列表,例如

from ema_calculator_pybind11 import *
import numpy as np
calculate_ema(np.array([
(1.0, 1.2, 0.9, 1.05, 100),
(100.0, 150.0, 90.0, 100.0, 200)
], dtype=Ohlc))

numpy试图分配给各个字段,而不是数据类型本身。