This is a very common use case for me. I have a C function that returns me a double pointer:
I know the sizes of the returned data. I also know that Fortran data is ordered. I want to write Cython "shim" to get the data in Python as a Numpy array:
#myshim.pyx import numpy cimport numpy as cnumpy cnumpy.import_array() cdef extern from "myheader.h" : double *mycfunction(...) def mypyfunc(...) : cdef double *data = mycfunction(...) **MAGIC** return outarray
MAGIC Ideas
(A) cdef cnumpy.ndarray[ cnumpy.double_t, mode='fortran', ...] outarray
That would be the most convenient way to do something. However, something critical that I'm missing here is how to turn the data
pointer into a buffer that I can pass to the cnumpy.ndarray constructor. I tried:
cdef cnumpy.ndarray[ cnumpy.double_t, mode='fortran', ...] outarray cdef bytes databuffer = <char *>data outarray = numpy.ndarray(buffer=databuffer, dtype=numpy.double, ...)
This approach fails sequentially with TypeError: buffer is too small for requested array
(B) Nump C-API
I used cnumpy.PyArray_SimpleNewFromData(...)
lot from Cython. It works great. The problem is that it does not support the flags argument, so I cannot tell it to build a Fortran array. An alternative that I used in pure C implementations is PyArray_NewFromDescr(...)
. He accepts the flags. This approach is long and painful and means getting some characters from numpy through an extern
block that has not yet been imported. There has to be a better way.
I searched my face for this problem, but nothing obvious came up. Maybe I'm an idiot. Or just sleep. Hooray!
source share