为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 CFFI 将多维 Numpy 数组传递给 C 函数?

如何使用 CFFI 将多维 Numpy 数组传递给 C 函数?

慕桂英546537 2023-12-20 19:59:22
我试图通过在 C++ 中实现一个函数并使用 CFFI 将其嵌入到我的代码中来加速我的 Python 程序。该函数采用两个 3x3 数组并计算距离。Python代码如下:import cffiimport numpy as npffi = cffi.FFI()ffi.cdef("""    extern double dist(const double s[3][3], const double t[3][3]);""")lib = ffi.dlopen("./dist.so")S = np.array([[-1.63538,  0.379116, -1.16372],[-1.63538, 0.378137, -1.16366 ],[-1.63193, 0.379116, -1.16366]], dtype=np.float32)T = np.array([[-1.6467834, 0.3749715, -1.1484985],[-1.6623441, 0.37410975, -1.1647063 ],[-1.6602284, 0.37400728, -1.1496595 ]], dtype=np.float32)Sp = ffi.cast("double(*) [3]", S.ctypes.data)Tp = ffi.cast("double(*) [3]", T.ctypes.data)dd = lib.dist(Sp,Tp);该解决方案无法按预期工作。事实上,C 函数打印的参数是: Sp=[[0.000002,  -0.270760,  -0.020458]    [0.000002,  0.000000,  0.000000]    [0.000000,  0.000000,  0.000000]] Tp=[[0.000002,  -0.324688,  -0.020588]    [0.000002,  0.000000,  0.000000]    [0.000000,  0.000000,  -nan]]我还尝试了以下方法来初始化指针:Sp = ffi.new("double *[3]")for i in range(3):    Sp[i] = ffi.cast("double *", S[i].ctypes.data)Tp = ffi.new("double *[3]")for i in range(3):    Tp[i] = ffi.cast("double *", T[i].ctypes.data)dd = lib.dist(Sp,Tp);但这个解决方案会出现错误dist(Sp,Tp):TypeError: initializer for ctype 'double(*)[3]' must be a pointer to same type, not cdata 'double *[3]'您知道如何使其发挥作用吗?谢谢。
查看完整描述

1 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

类型double[3][3]double *[3]不等效。前者是一个 double 3x3 的 2D 数组,存储为 9 个连续的 double。后者是一个由 3 个双指针组成的数组,这不是 C 或 C++ 中 2D 静态数组的实现方式。

numpy 数组和 C++ 静态数组在内存中都表示为连续的元素块,只是double *[3]中间的类型给工作带来了麻烦。您想要的是使用double[3][3]正确的 or double[3]*(指向一行三个双精度数的指针)。请注意,如果您使用后者,您可能需要将函数原型更改为 take double [][3]


查看完整回答
反对 回复 2023-12-20
  • 1 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信