Reputation: 354
I want to use the data from an c array in cython/python code.
To do so I tried to convert the c array with numpy.ctypeslib.ndpointer
.
I get the error Cannot convert 'float *' to Python object
.
Below is a simple example I tried to get up and running for a couple of days now.
Lets say we have a c function that creates an array. 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;
}
In cython I have 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)
Upvotes: 1
Views: 2349
Reputation: 354
@DavidW pointed you that numpy.ctypeslib.ndpointer
is not the right way to go for what I want to do.
Basically I just want to convert an c-array
to an cython/python-array
.
With help of this link I found the answer: http://docs.cython.org/src/userguide/memoryviews.html#cython-arrays
def py_compute(int size):
return <float[:size]> (compute(size))
I'm freeing the memory in c so that I dont have to worry about freeing it in python and therefor can use this really simple solution.
Upvotes: 2