Pass a 2d numpy array to c using ctypes

前端 未结 3 1083
天涯浪人
天涯浪人 2020-12-13 22:45

What is the correct way to pass a numpy 2d - array to a c function using ctypes ? My current approach so far (leads to a segfault):

C code :

void te         


        
3条回答
  •  渐次进展
    2020-12-13 23:27

    This is probably a late answer, but I finally got it working. All credit goes to Sturla Molden at this link.

    The key is, note that double** is an array of type np.uintp. Therefore, we have

    xpp = (x.ctypes.data + np.arange(x.shape[0]) * x.strides[0]).astype(np.uintp)
    doublepp = np.ctypeslib.ndpointer(dtype=np.uintp)
    

    And then use doublepp as the type, pass xpp in. See full code attached.

    The C code:

    // dummy.c 
    #include  
    
    __declspec(dllexport) void foobar(const int m, const int n, const 
    double **x, double **y) 
    { 
        size_t i, j; 
        for(i=0; i

    The Python code:

    # test.py 
    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 = np.zeros_like(x) 
        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 y 
    
    if __name__ == '__main__': 
        x = np.arange(9.).reshape((3, 3)) 
        y = foobar(x) 
    

    Hope it helps,

    Shawn

提交回复
热议问题