How to pass a Numpy array into a cffi function and how to get one back out?
arrays, numpy, python, python-cffi
Solution
The `ctypes` attribute of ndarray can interact with the ctypes module, for example, `ndarray.ctypes.data` is the data address of the array, you can cast it to a `float *` pointer, and then pass the pointer to the C function.
import numpy as np
from cffi import FFI
ffi = FFI()
ffi.cdef("void copy(float *in, float *out, int len);")
C = ffi.dlopen("ccode.dll")
a = 42*np.ones(16, dtype=np.float32)
b = np.zeros_like(a)
pa = ffi.cast("float *", a.ctypes.data)
pb = ffi.cast("float *", b.ctypes.data)
C.copy(pa, pb, len(a))
print b
For your question 3:
I think ffi array doesn't provide numpy the necessary information to access it's inner buffer. So numpy try to convert it to a float number which failed.
The best solution I can thinks is convert it to list first:
float_in[0:16] = list(arr_in[0:16])
Problem
I am developing an audio algorithm using Python and Numpy. Now I want to speed up that algorithm by implementing a part of it in C. In the past, I have done this using cython. Now I want to do the same thing using the new cffi. For testing purposes, I wrote a trivial C function: ``` void copy(float *in, float *out, int len) { for (int i=0; i<len; i++) { out[i] = in[i]; } } ``` Now I want to create two numpy arrays and have those be processed by this function. I figured out a way to do that: ``` import numpy as np from cffi import FFI ffi = FFI() ffi.cdef("void copy(float *in, float *out, int len);") C = ffi.dlopen("/path/to/copy.dll") float_in = ffi.new("float[16]") float_out = ffi.new("float[16]") arr_in = 42*np.ones(16, dtype=np.float32) float_in[0:16] = arr_in[0:16] C.copy(float_in, float_out, 16) arr_out = np.frombuffer(ffi.buffer(float_out, 16*4), dtype=np.float32) ``` However, I would like to improve this code: - Is there a way to directly access the underlying float buffers of the numpy arrays without copying them? - `ffi.buffer` is very convenient for quickly converting to contents of a C array to a Numpy array. Is there an equivalent way for quickly converting a numpy array into a C array without copying the individual elements? - For some applications, `float_in[0:16] = arr_in[0:16]` is a convenient way of accessing data. The opposite, `arr_out[0:16] = float_out[0:16]` does not work however. Why not?