如何使用ctypes将C函数中返回的2d数组传递给python

我有一个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])并使用嵌套循环将数据复制到该缓冲区中.

相关文章

在这篇文章中,我们深入学习了XPath作为一种常见的网络爬虫技巧。XPath是一种用于定位和选择XML文档中特...
祝福大家龙年快乐!愿你们的生活像龙一样充满力量和勇气,愿你们在新的一年里,追逐梦想,勇往直前,不...
今天在爬虫实战中,除了正常爬取网页数据外,我们还添加了一个下载功能,主要任务是爬取小说并将其下载...
完美收官,本文是爬虫实战的最后一章了,所以尽管本文着重呈现爬虫实战,但其中有一大部分内容专注于数...
JSON是一种流行的数据传输格式,Python中有多种处理JSON的方式。官方的json库是最常用的,它提供了简单...
独立样本T检验适用于比较两组独立样本的均值差异,而配对T检验则适用于比较同一组样本在不同条件下的均...