Python C API 分段错误

Python C API segmentation fault

我试图将数组从 C 传递到 python 并执行简单的算术运算 numpy.prod,但遇到了分段错误。谁能帮我指出哪里出了问题?谢谢!

#include <Python.h>
#include <stdio.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "/share/apps/anaconda2/pkgs/numpy-1.10.4-py27_1/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h"

double Array[4] = {1.0, 2.0, 3.0, 4.0};

double call_func(PyObject *func, double array[]){
        PyObject *args;
        PyObject *kwargs;
        PyObject *result;
        npy_intp dims[1] = {4};
        double retval;

        PyGILState_STATE state = PyGILState_Ensure();

        if (!PyCallable_Check(func)){
                printf("%s", "Function is not callable!\n");
        }

        args = PyArray_SimpleNewFromData(1, dims, NPY_FLOAT32, array);
        kwargs = NULL;

        result = PyObject_Call(func, args, kwargs);
        Py_DECREF(args);
        Py_XDECREF(kwargs);

        if (PyErr_Occurred()){
                PyErr_Print();
        }

        if (!PyFloat_Check(result)){
                printf("%s", "Callable did not return a float!");
        }

        retval = PyFloat_AsDouble(result);
        Py_DECREF(result);

        PyGILState_Release(state);
        return retval;
}

PyObject *import_name(const char *modname, const char *symbol){
        PyObject *mymodule = PyImport_ImportModule(modname);
        return PyObject_GetAttrString(mymodule, symbol);
}

void main(){
        PyObject *myfunc;
        double retval;

        import_array();

        Py_Initialize();

        myfunc = import_name("numpy", "prod");

        retval = call_func(myfunc, Array);
        Py_DECREF(myfunc);

        printf("%d\n", retval);

        Py_Finalize();
}

(我遵循了本网站上的程序 http://blog.numerix-dsp.com/2013/08/how-to-pass-c-array-to-python-solution.html?m=1。)

除了错误地构造您的数组对象,如评论中所述,您的 PyObject_Call() 调用的第二个参数似乎是错误的。根据 its docs,第二个参数应指向一个元组,在您的情况下,该元组应包含您的数组对象作为其单个元素,但您传递的是数组对象本身。根据该函数或被调用函数检查其参数的仔细程度,这种不匹配很容易导致段错误。

此外,如果没有关键字参数,那么您可以只传递文字 NULL 作为第三个参数。在任何情况下,既然你可以确定变量 kwargsNULL,那么 Py_XDECREF() 它似乎有点毫无意义(尽管没有错误)。