gpt4 book ai didi

python - 使用 ctypes 将 2d numpy 数组传递给 c

转载 作者:太空狗 更新时间:2023-10-29 18:18:42 27 4
gpt4 key购买 nike

使用 ctypes 将 numpy 二维数组传递给 c 函数的正确方法是什么?到目前为止我目前的方法(导致段错误):

C 代码:

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代码:

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)

最佳答案

这可能是一个迟到的答案,但我终于让它工作了。所有功劳归于 Sturla Molden,地址为 this link

关键是,注意 double**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。完整代码见附件。

C 代码:

// 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];
}

Python 代码:

# 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)

希望对你有帮助

肖恩

关于python - 使用 ctypes 将 2d numpy 数组传递给 c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22425921/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com