Great thanks to both Strula and also Nathaniel!

@Strula, thanks for your help! And I do think your solution makes
total sense. However, the code doesn't work well on my computer.

----------------
// dummy.c
#include <stdlib.h>

__declspec(dllexport) void foobar(const int m, const int n, const
double **x, double **y)
{
    size_t i, j;
    y = (** double)malloc(sizeof(double *) * m);
    for(i=0; i<m; i++)
        y[i] = (*double)calloc(sizeof(double), n);
    for(i=0; i<m; i++)
        for(j=0; j<n; j++)
            y[i][j] = x[i][j];
}
----------------

And then, I was using MSVC, I did cl /LD dummy.c to generate dummy.dll

And then:

----------------
import numpy as np
from numpy.ctypeslib import ndpointer
import ctypes

_doublepp = ndpointer(dtype=np.uintp, ndim=1, flags='C')
_dll = ctypes.CDLL('dummy.dll')
_foobar = _dll.foobar
_foobar.argtypes = [ctypes.c_int, ctypes.c_int, _doublepp, _doublepp]
_foobar.restype = None

def foobar(x, y):
    assert x.shape == y.shape
    xpp = (x.__array_interface__['data'][0]
        + np.arange(x.shape[0])*x.strides[0]).astype(np.uintp)
    ypp = (y.__array_interface__['data'][0]
      + np.arange(y.shape[0])*y.strides[0]).astype(np.uintp)
    m = ctypes.c_int(x.shape[0])
    n = ctypes.c_int(x.shape[1])
    _foobar(m, n, xpp, ypp)
    return x, y

if __name__ == '__main__':
    x = np.arange(9.).reshape((3, 3))
    y = np.zeros_like(x)
    xnew, ynew = foobar(x, y)

----------------

The result is:

ynew
Out[76]:
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])


Was I doing something wrong here?

Shawn

On Thu, Jan 1, 2015 at 1:56 PM, Nathaniel Smith <[email protected]> wrote:
> On Thu, Jan 1, 2015 at 6:00 PM, Yuxiang Wang <[email protected]> wrote:
>> Dear all,
>>
>> I am currently using a piece of C code, where one of the input
>> argument of a function is **double.
>
> As you discovered, Numpy's ctypes utilities are helpful for getting a
> *double out of an ndarray, but they don't really have anything to do
> with **double's -- for that you should refer to the plain-old-ctypes
> documentation: https://docs.python.org/2/library/ctypes.html#ctypes.pointer
>
> However, I suspect that this question can't really be answered in a
> useful way without more information about why exactly the C code wants
> a **double (instead of a *double) and what it expects to do with it.
> E.g., is it going to throw away the passed in array and return a new
> one?
>
> -n
>
> --
> Nathaniel J. Smith
> Postdoctoral researcher - Informatics - University of Edinburgh
> http://vorpus.org
> _______________________________________________
> NumPy-Discussion mailing list
> [email protected]
> http://mail.scipy.org/mailman/listinfo/numpy-discussion



-- 
Yuxiang "Shawn" Wang
Gerling Research Lab
University of Virginia
[email protected]
+1 (434) 284-0836
https://sites.google.com/a/virginia.edu/yw5aj/
_______________________________________________
NumPy-Discussion mailing list
[email protected]
http://mail.scipy.org/mailman/listinfo/numpy-discussion

Reply via email to