1

I want to pass a numpy array into some(one else's) C++ code via CFFI. Assume I cannot (in any sense) change the C++ code, whose interface is:

double CompactPD_LH(int Nbins, double * DataArray, void * ParamsArray ) {
    ...
}

I pass Nbins as a python integer, ParamsArray as a dict -> structure, but DataArray (shape = 3 x NBins, which needs to be populated from a numpy array, is giving me a headache. (cast_matrix from Why is cffi so much quicker than numpy? isn't helping here :(

Here's one attempt that fails:

from blah import ffi,lib
data=np.loadtxt(histof)
DataArray=cast_matrix(data,ffi) # see https://stackoverflow.com/questions/23056057/why-is-cffi-so-much-quicker-than-numpy/23058665#23058665
result=lib.CompactPD_LH(Nbins,DataArray,ParamsArray)

For reference, cast_matrix was:

def cast_matrix(matrix, ffi):
    ap = ffi.new("double* [%d]" % (matrix.shape[0]))
    ptr = ffi.cast("double *", matrix.ctypes.data)
    for i in range(matrix.shape[0]):
        ap[i] = ptr + i*matrix.shape[1]
    return ap 

Also:

How to pass a Numpy array into a cffi function and how to get one back out?

https://gist.github.com/arjones6/5533938

Community
  • 1
  • 1
jtlz2
  • 7,700
  • 9
  • 64
  • 114
  • 1
    Well, this `cast_matrix` function is for an "array of arrays", not a 1D array (`double **` vs. `double *`). I think you just need `DataArray = ffi.cast("double *", data.ctypes.data)`. Make sure `data` is C-contiguous. –  Jun 18 '16 at 09:06
  • Thanks - works! :) – jtlz2 Jun 18 '16 at 09:59

1 Answers1

2

Thanks @morningsun!

dd=np.ascontiguousarray(data.T)
DataArray = ffi.cast("double *",dd.ctypes.data)
result=lib.CompactPD_LH(Nbins,DataArray,ParamsArray)

works!

jtlz2
  • 7,700
  • 9
  • 64
  • 114