从python3 C扩展返回数组

时间:2019-03-11 09:04:16

标签: python-3.x python-c-api

我希望在C扩展模块中生成数组,并将它们传递回python。

以下代码适用于 python2

C_generate_array.c:

#include "Python.h"
#include "arrayobject.h"
#include "C_generate_array.h"
#include <assert.h>

static PyMethodDef C_generate_arrayMethods[] = {
    {"get_array", get_array, METH_VARARGS},
    {NULL, NULL}     /* Sentinel - marks the end of this structure */
};

#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef cModPyDem =
{
    PyModuleDef_HEAD_INIT,
    "C_generate_array", /* name of module */
    "",          /* module documentation, may be NULL */
    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    C_generate_arrayMethods
};
PyMODINIT_FUNC PyInit_C_generate_array(void)
{
    return PyModule_Create(&cModPyDem);
}
#else
void initC_generate_array()  {
    (void) Py_InitModule("C_generate_array", C_generate_arrayMethods);
    import_array();  // Must be present for NumPy.  Called first after above line.
}
#endif

static PyObject *get_array(PyObject *self, PyObject *args)
{
    int dims[2];
    dims[0]=dims[1]=2;
    PyArrayObject *matout;
#if PY_MAJOR_VERSION >= 3
    //what to do here?
    return PyLong_FromLong(1);
#else
    matout = (PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE);
    return PyArray_Return(matout);
#endif
}

C_generate_array.h:

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
#endif

typedef int bool;
#define true 1
#define false 0


static PyObject *get_array(PyObject *self, PyObject *args);

C_generate_array_setup.py:

from distutils.core import setup, Extension
module1 = Extension('C_generate_array',
                    include_dirs = ['path_to_python/lib/python3.5/','path_to_python/lib/python3.5/site-packages/numpy/core/include/numpy/'],
                    sources = ['C_generate_array.c'])
setup (name = 'C_generate_array',
       version = '1.0',
       description = 'Example',
       ext_modules = [module1])

然后构建和安装:

>sudo python2.7 C_generate_array_setup.py build
>sudo python2.7 C_generate_array_setup.py install
>python2.7
>>> import C_generate_array
>>> C_generate_array.get_array()
array([[0., 0.],
       [0., 0.]])

但是,python3的等效功能是什么?我只找到了一种返回标量变量的方法:

>sudo python3.5 C_generate_array_setup.py build
>sudo python3.5 C_generate_array_setup.py install
>python3.5
>>> import C_generate_array
>>> C_generate_array.get_array()
1

如何返回数组?

1 个答案:

答案 0 :(得分:0)

我认为问题在于PyArray_FromDims是一个非常老的API函数,不再推荐使用,并且可能已从Numpy标头中删除。我不知道为什么它似乎适用于Python 2,但是您可能在其中安装了较旧版本的Numpy。

我建议您改用PyArray_ZEROS,它具有基本相同的接口,并带有附加参数来标记数组是否应为Fortran连续的(您可能希望将其设置为0)。如果要将数组填充为零以外的其他值,请选择其他函数(请阅读我链接的文档)。