通过二维数组numpy的使用ctypes的

通过二维数组numpy的使用ctypes的

本文介绍了通过二维数组numpy的使用ctypes的ç的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是传递一个numpy的2D正确的方式 - 阵列使用ctypes的C函数?
我目前的做法至今(导致段错误):

C code:

 无效测试(双** in_array,INT N){
    INT I,J;
        对于(i = 0; I< N;我++){
            为(J = 0; J< N; J ++){
                的printf(%E \\ t的,in_array [I] [J]);
        }
        的printf(\\ n);
    }
}

蟒蛇code:

 从ctypes的导入*
进口numpy.ctypeslib作为npctarray_2d_double = npct.ndpointer(DTYPE = np.double,NDIM = 2,旗帜='毗连')
liblr = npct.load_library('libtest.so','./src')liblr.test.restype =无
liblr.test.argtypes = [array_2d_double,c_int的]X = np.arange(100).reshape((10,10))。astype(np.double)
liblr.test(X,10)


解决方案

这可能是一个迟到的答案,但我终于得到了它的工作。一切归功于Sturla莫尔登在此链接。

最关键的是,请注意,双** 是类型的数组 np.uintp 。因此,我们有

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

然后用 doublepp 作为类型,通 XPP 。请参见全code连接。

在C code:

  // dummy.c
#包括LT&;&stdlib.h中GT;__declspec(dllexport)的无效​​foobar的(const int的男,const int的N,常量
双** X,双** Y)
{
    为size_t I,J;
    对于(i = 0; I<米;我++)
        为(J = 0; J< N; J ++)
            Y [I] [J] = X [I] [J]。
}

Python的code:

 #test.py
导入numpy的是NP
从numpy.ctypeslib进口ndpointer
进口ctypes的_doublepp = ndpointer(DTYPE = np.uintp,NDIM = 1,旗帜='C')_DLL = ctypes.CDLL('dummy.dll')_foobar = _dll.foobar
_foobar.argtypes = [ctypes.c_int,ctypes.c_int,_doublepp,_doublepp]
_foobar.restype =无高清foobar的(X):
    Y = np.zeros_like(X)
    XPP =(X .__ array_interface __ ['数据'] [0]
      + np.arange(x.shape [0])* x.strides [0])。astype(np.uintp)
    YPP =(Y .__ array_interface __ ['数据'] [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)
    返回是如果__name__ =='__main__':
    X = np.arange(9)。重塑((3,3))
    Y = foobar的(X)

希望它帮助,

肖恩

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 test(double **in_array, int N){
    int i,j;
        for(i = 0; i<N; i++){
            for(j = 0; j<N; j++){
                printf("%e \t", in_array[i][j]);
        }
        printf("\n");
    }
}

python code:

from ctypes import *
import numpy.ctypeslib as npct

array_2d_double = npct.ndpointer(dtype=np.double,ndim=2, flags='CONTIGUOUS')
liblr = npct.load_library('libtest.so', './src')

liblr.test.restype = None
liblr.test.argtypes = [array_2d_double, c_int]

x = np.arange(100).reshape((10,10)).astype(np.double)
liblr.test(x, 10)
解决方案

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 <stdlib.h>

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

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

这篇关于通过二维数组numpy的使用ctypes的ç的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 05:51