Numpy,在 C++ 段错误中创建一维数组
Posted
技术标签:
【中文标题】Numpy,在 C++ 段错误中创建一维数组【英文标题】:Numpy, creating 1D array in C++ segfaults 【发布时间】:2017-03-14 12:32:27 【问题描述】:我正在尝试在 C++ 中为 numpy 创建一维数组:
PyObject* foo()
npy_intp length[1];
length[0] = 10;
PyObject* my_array = PyArray_SimpleNew(1, length, NPY_DOUBLE);
return boost::python::incref(my_array);
然后我做一个python模块:
BOOST_PYTHON_MODULE(pyMod)
using namespace boost::python;
import_array();
def("foo", foo);
当我在 python 中运行它时,调用 foo(),它在执行对 PyArray_SimpleNew 的调用时会出现段错误,即使我已经调用了 import_array,这似乎是导致这种段错误的常见原因。如果我制作一个维度为 [10, 1] 的二维数组,则效果很好,即:
PyObject* foo()
npy_intp length[2] = 10, 1;
PyObject* my_array = PyArray_SimpleNew(2, length, NPY_DOUBLE);
return boost::python::incref(my_array);
在python中是这样使用的
import numpy as np
import pyMod
if __name__ == "__main__":
v = pyMod.foo()
对为什么会出现此段错误有任何想法吗?
【问题讨论】:
在哪一行出现段错误?请提供带有详细错误消息的minimal reproducible example(不只是一个函数;向我们展示你如何调用它) 调用 PyArray_SimpleNew 时出现段错误 我的评论不仅仅是第一句话。 【参考方案1】:我不确定您是如何将 PyObject* 暴露给 Python,但我认为正确的方法是通过 boost::python::object 暴露它。
另一点是您正在使用 PyObject 调用 boost::python::object。尽管有可能,但不建议这样做(参见 David Abrahams 撰写的 guidelines)。所以应该使用 boost::python::handle 来解决这种情况。
boost::python::object foo()
npy_intp dims[1] = 10;
PyObject* p_array = PyArray_SimpleNew(boost::size(dims), dims, NPY_FLOAT);
boost::python::handle<> handle(boost::python::borrowed(p_array));
return boost::python::object(handle);
【讨论】:
不要认为这是问题所在,因为它在返回之前会崩溃并适用于 2D 数组。不过谢谢你的回答。 仅仅因为它使用二维数组并不意味着它是正确的。我已经编辑了答案,提供了一个解释句柄重要性的链接。 但是我需要一个来自 boost::python::object 的转换器,它只返回 incref(boost_py_obj->ptr()): PyObject* convert(boost::python::object obj) 返回 boost::python::incref(obj->ptr)); ? 我已将问题编辑为不使用 boost::python::object,然后我不需要句柄,因为我没有通过 boost::python::object?以上是关于Numpy,在 C++ 段错误中创建一维数组的主要内容,如果未能解决你的问题,请参考以下文章