I\'m writing a C extension to my Python program for speed purposes, and running into some very strange behaviour trying to pass in a 3-dimensional numpy array. It works with a 2
According to http://docs.scipy.org/doc/numpy/reference/c-api.array.html?highlight=pyarray_ascarray#PyArray_AsCArray:
Note The simulation of a C-style array is not complete for 2-d and 3-d arrays. For example, the simulated arrays of pointers cannot be passed to subroutines expecting specific, statically-defined 2-d and 3-d arrays. To pass to functions requiring those kind of inputs, you must statically define the required array and copy data.
I think that this means that PyArray_AsCArray
returns a block of memory with the data in it in C order. However, to access that data, more information is needed (see http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation). This can either be achieved by knowing the dimensions ahead of time, declaring an array, and then copying the data in in the right order. However, I suspect that more general case is more useful: you don't know the dimensions until they are returned. I think that the following code will create the necessary C pointer framework to allow the data to be addressed.
static PyObject* func(PyObject* self, PyObject* args) {
PyObject *list2_obj;
PyObject *list3_obj;
if (!PyArg_ParseTuple(args, "OO", &list2_obj, &list3_obj)) return NULL;
double **list2;
double ***list3;
// For the final version
double **final_array2;
double **final_array2;
// For loops
int i,j;
//Create C arrays from numpy objects:
int typenum = NPY_DOUBLE;
PyArray_Descr *descr;
descr = PyArray_DescrFromType(typenum);
// One per array coming back ...
npy_intp dims2[2];
npy_intp dims3[3];
if (PyArray_AsCArray(&list2_obj, (void **)&list2, dims2, 2, descr) < 0 || PyArray_AsCArray(&list3_obj, (void ***)&list3, dims3, 3, descr) < 0) {
PyErr_SetString(PyExc_TypeError, "error converting to c array");
return NULL;
}
// Create the pointer arrays needed to access the data
// 2D array
final_array2 = calloc(dim2[0], sizeof(double *));
for (i=0; i
I couldn't find a definition for npy_intp
, the above assumes it is the same as int
. If it isn't you will need to convert dim2
and dim3
into int
arrays before doing the code.