pybind11 返回 numpy 对象数组
Posted
技术标签:
【中文标题】pybind11 返回 numpy 对象数组【英文标题】:pybind11 return numpy array of objects 【发布时间】:2017-07-16 03:30:34 【问题描述】:使用 pybind11 C++ API 和 python3,我们如何在 C++ 实现中正确地创建一个 numpy 对象数组(即 unicode 字符串)并将其返回给 python?传递给 pybind11::array() 的底层数据数组的确切内存布局是什么?我们究竟需要如何管理内存,即删除/释放?
请注意,这是必要的,因为我们希望在创建 pandas DataFrame 时将该字符串数组与其他 POD 数组结合使用。
【问题讨论】:
我对@987654321@ 无能为力。但是numpy
数组可以使用numpy C API
函数创建。数组布局基本相同,属性加数据缓冲区。对于对象类型,数据缓冲区包含指向内存中其他位置的对象的指针。使用unicode
dtype,缓冲区实际上包含字符串(填充到指定长度)。您可能需要学习 numpy
文档。
谢谢 - 似乎最好的方法是手动创建带有对象的缓冲区,然后弄清楚 pybind11 如何管理与底层数组以及所有对象关联的内存...
【参考方案1】:
事实证明有必要:
创建一个 PyObject 指针数组,填充数组,即
auto* pbuf = new PyObject*[arraySize]; // or create via pybind11 API...
pbuf[0] = <new object...>
pbuf[1] = <new object...>
etc.
创建一个带有胶囊的“对象” py::array():
py::capsule freeWhenDone(pbuf, [](void* pp)
delete [] (PyObject*)pp; // or else properly free the pbuf memory
);
arr = py::array(py::dtype("object"),
shape, strides, pbuf, freeWhenDone);
【讨论】:
您还知道不需要freeWhenDone
的解决方案吗?我想如果内存被 pybind11 malloc'd,py::array 可以使用正常的 free'ing。
我能够让它工作而不泄漏的方法是使用胶囊。此外,当内部对象是 python 字符串时,我必须释放每个单独分配的对象。更新版本的pybind11可能还有其他解决方案。以上是关于pybind11 返回 numpy 对象数组的主要内容,如果未能解决你的问题,请参考以下文章
使用 carma(犰狳矩阵和 numpy 数组)用 pybind11 包装 c++ 类时出错