I have had success in sending numpy arrays to c functions with Cython. Whenever I have a function in c that takes int *
and I have some variable in python, call itarr
, that is 1D numpy array I just call the function with &arr[0]
and it works.
Now I'm interested in receiving a 2D array created with a c function. How can I do this? Below is what I've tried.
// this is the c code that returns a 2D array
int **make_array() {
int nrows = 3;
int ncols = 5;
int **ret = malloc(nrows * sizeof(int *));
ret[0] = calloc(nrows * ncols, sizeof(int));
for (int i = 1; i < nrows; i++) {
ret[i] = ret[0] + i * ncols;
}
int count = 0;
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
ret[i][j] = ++count;
return ret;
}
python code
# python code that receives the 2D array
def foo():
cdef int nRows = 3
cdef int nCols = 5
cdef int[:,::1] ret = np.zeros((nRows, nCols), dtype=np.int32)
ret = make_array()
This gives me the following error for the last line of the function:
Cannot convert 'int **' to memoryviewslice
If I don't create a memoryview and instead have some variable created at the point of the call to receive the output the assignment to the variable will work fine. The problem is that I still can't figure out how to work with the returned value. For example I can't do this:
# python code that receives the 2D array
def foo():
cdef int nRows = 3
cdef int nCols = 5
ret = make_array() # works
print(ret) # fails
It complaints with the same error:
Cannot convert 'int **' to Python object
How can one work with int **
returned from a c function?