我有一个C函数返回2d数组(实际上是double **),我想使用ctypes将此double **传递给python.对此有疑问,但是在参数列表中而不是使用函数的返回值来修改数组.这是我的代码(C函数和相应的python包装器)
double** flux_function_2d(double *u,double gamma){
double **F;
double p,H;
F = (double **)malloc(4*sizeof(double *));
for (int i = 0; i < 4; i++)
F[i] = (double *)malloc(2*sizeof(double));
p = (gamma - 1.0) * (u[3] - 0.5 * (u[1]*u[1] + u[2]*u[2]) / u[0]);
H = u[3] / u[0] + p / u[0];
F[0][0] = u[1]; F[1][0] = u[1] * u[1] / u[0] + p;
F[2][0] = u[1] * u[2] / u[0]; F[3][0] = u[1] * H;
F[0][1] = u[2]; F[1][1] = u[2] * u[1] / u[0];
F[2][1] = u[2] * u[2] / u[0] + p; F[3][1] = u[2] * H;
return F;
}
def c_flux_function_2d(u,gamma):
flux = np.ctypeslib.load_library("libs/flux.so",".")
flux.flux_function_2d.argtypes = [POINTER(c_double),c_double]
flux.flux_function_2d.restype = POINTER(POINTER(c_double))
F = flux.flux_function_2d(u.ctypes.data_as(POINTER(c_double)),c_double(gamma))
F_arr = np.ctypeslib.as_array(F,shape=(4,2))
return F_arr
该错误发生在F_arr = np.ctypeslib.as_array(F,shape =(4,2))处,这意味着numpy无法解析ctypes中的指针的指针.
提前致谢!
最佳答案
如果实际上有一个2D数组,则可以调用numpy.ctypeslib.as_array,但没有.
您有一个指向其他数组的第一个元素的指针数组的第一个元素的指针.这与2D数组是完全不同的,只是恰好可以使用C中相同的语法进行索引.
您所拥有的内存布局与NumPy完全不兼容. NumPy数组具有单个存储缓冲区,其中包含形状和步幅信息,这些信息告诉您每个维度可以走多远以及每个步骤必须走多少字节.
对于C连续数组(最常见的情况),MxN数组缓冲区的内存布局与C whattype [M] [N]相同.相比之下,数据结构的子数组分散在任意内存位置中,而在第一维中则没有跨步.
您需要将数据放入NumPy可以使用的布局中.有多种方法可以做到这一点,包括仅在C函数中分配并使用连续缓冲区,或者创建numpy.empty([4,2])并使用嵌套循环将数据复制到该缓冲区中.