cython:使用numpy.ctypeslib.ndpointer将float数组转换为python数组

时间:2015-10-13 13:35:00

标签: python c arrays numpy cython

我想在cython / python代码中使用c数组中的数据。

为此,我尝试使用numpy.ctypeslib.ndpointer转换c数组 我收到错误Cannot convert 'float *' to Python object

下面是一个简单的例子,我试图启动并运行几天。

假设我们有一个创建数组的c函数。 c_code.c

float *compute(int size)
{
    float* array;
    array = malloc(sizeof(float)*size);
    int i;
    for (i=0; i<size; i++)
    {
       array[i] = i;
    }
    return array;
}

在cython中我有cython_wrapper.pyx

# Declare the prototype of the C function we are interested in calling
cdef extern from "c_code.c":
    float*compute(int size)

# Import the Python-level symbols of numpy
import numpy as np

# Import the C-level symbols of numpy
cimport numpy as np
import ctypes

# Numpy must be initialized. When using numpy from C or Cython you must
# _always_ do that, or you will have segfaults
np.import_array()

def py_compute(int size):
    """ Python binding of the 'compute' function in 'c_code.c' that does
        not copy the data allocated in C.
    """
    cdef float *array
    cdef np.ndarray ndarray
    # Call the C function
    array = compute(size)

    func = np.ctypeslib.ndpointer(dtype=ctypes.c_int, shape=(size,))
    ndarray = func(array)
    return ndarray

setup.py

import numpy
from Cython.Distutils import build_ext


def configuration(parent_package='', top_path=None):
    """ Function used to build our configuration.
    """
    from numpy.distutils.misc_util import Configuration

    # The configuration object that hold information on all the files
    # to be built.
    config = Configuration('', parent_package, top_path)
    config.add_extension('cython_wrapper',
                         sources=['cython_wrapper.pyx'],
                         # libraries=['m'],
                         depends=['c_code.c'],
                         include_dirs=[numpy.get_include()])
    return config


if __name__ == '__main__':
    # Retrieve the parameters of our local configuration
    params = configuration(top_path='').todict()

    # Override the C-extension building so that it knows about '.pyx'
    # Cython files
    params['cmdclass'] = dict(build_ext=build_ext)

    # Call the actual building/packaging function (see distutils docs)
    from numpy.distutils.core import setup

    setup(**params)

1 个答案:

答案 0 :(得分:2)

@DavidW指出numpy.ctypeslib.ndpointer不适合我想做的事。

基本上我只想将c-array转换为cython/python-array

借助此链接,我找到了答案: http://docs.cython.org/src/userguide/memoryviews.html#cython-arrays

def py_compute(int size):
    return <float[:size]> (compute(size))

我正在释放c中的内存,所以我不必担心在python中释放它,因此可以使用这个非常简单的解决方案。