【问题标题】:Crash when calling PyArg_ParseTuple on a Numpy array在 Numpy 数组上调用 PyArg_ParseTuple 时崩溃
【发布时间】:2016-10-22 23:01:13
【问题描述】:

我用 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))

我的代码有什么问题?

【问题讨论】:

    标签: python c arrays numpy


    【解决方案1】:

    我认为错误出现在您的示例中未包含的代码中:您是否记得在模块初始化函数中调用 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);
    }
    

    并且示例运行没有问题。另一方面,删除调用会导致崩溃。

    【讨论】:

    • 谢谢,它不再崩溃了!我读过的大多数教程都没有这个指令调用。
    • 这节省了我很多时间!!感谢您的解决方案和问题!
    【解决方案2】:

    MacOS 和 Linux 的区别

    以下内容在 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_Createimport_array 的顺序。

    【讨论】:

      猜你喜欢
      • 2019-12-20
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多