我在C中编写了一个简单的Python扩展函数,只读取Numpy数组并崩溃。
static PyObject *test(PyObject *self, PyObject *args)
{
PyArrayObject *array = NULL;
if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &array)) // Crash
return NULL;
return Py_BuildValue("d", 0);
}
以下是它的调用方式:
l = np.array([1,2,3,1,2,2,1,3])
print("%d" % extension.test(l))
我的代码出了什么问题?
答案 0 :(得分:4)
我认为错误出现在您未在示例中包含的代码中:您是否记得在模块初始化函数中调用import_array()
:
...此子例程还必须包含对import_array()和/或import_ufunc()的调用,具体取决于所需的C-API。只要实际调用任何C-API子例程,忘记放置这些命令就会显示为一个丑陋的分段错误(崩溃)。
http://docs.scipy.org/doc/numpy-1.10.1/user/c-info.how-to-extend.html#required-subroutine
我逐字复制你的例子并添加(使用python 3)
PyMODINIT_FUNC
PyInit_numpytest(void)
{
import_array();
return PyModule_Create(&numpytest);
}
并且示例运行没有问题。另一方面,删除呼叫会导致崩溃。
答案 1 :(得分:0)
以下在 Linux 上对我来说很好用:
PyMODINIT_FUNC PyInit_numpytest(void) {
import_array();
return PyModule_Create(&numpytest);
}
但是,在使用 MacOS 时,尝试导入库时出现以下错误:
SystemError: лy () method: bad call flags
以下适用于 MacOS 和 Linux:
PyMODINIT_FUNC PyInit_numpytest(void) {
PyObject* mod = PyModule_Create(&numpytest);
import_array();
return mod;
}
请注意,我所做的只是更改了 PyModule_Create
和 import_array
的顺序。