[Numpy-discussion] Pass 2d ndarray into C **double using ctypes

Sturla Molden sturla.molden at gmail.com
Thu Jan 1 13:30:42 EST 2015


You can pretend double** is an array of dtype np.intp. This is because 
on all modern systems, double** has the size of void*, and np.intp is an 
integer with the size of void* (np.intp maps to Py_intptr_t).

Now you just need to fill in the adresses. If you have a 2d ndarray in C 
order, or at least one which is contiguous along the second dimension, 
you set up the array of double* like so:

xpp = (x.__array_interface__['data'][0]
    + np.arange(x.shape[0])*x.strides[0]).astype(np.intp)

(The last cast to np.intp is probably only required on Windows 64 with 
older NumPy versions, but it never hurts.)

Next, make a dtype that corresponds to this Py_intptr_t array:

doublepp = np.ctypeslib.ndpointer(dtype=np.intp)

Declare your function with doublepp instead of ndpointer with dtype 
np.double, and pass xpp instead of the 2d array x.


Sturla



On 01/01/15 19:00, Yuxiang Wang wrote:
> Dear all,
>
> I am currently using a piece of C code, where one of the input
> argument of a function is **double.
>
> So, in numpy, I tried np.ctypeslib.ndpointer(ctypes.c_double), but
> obviously this wouldn't work because this is only *double, not
> **double.
>
> Then I tried np.ctypeslib.ndpointer(np.ctypeslib.ndpointer(ctypes.c_double)),
> but this didn't work either because it says "ArgumentError: argument
> 4: <class 'TypeError'>: array must have data type uint64
> ".
>
> np.ctypeslib.ndpointer(ctypes.c_double, ndim=2) wound't work too,
> because **double is not the same with *double[].
>
> Could anyone please give any thoughts to help?
>
> Thanks,
>
> Shawn
>





More information about the NumPy-Discussion mailing list