在Cython中传递输入/输出给函数

1 投票
1 回答
1416 浏览
提问于 2025-04-18 06:21

我正在尝试用Cython写一个函数,这个函数需要从Python接收一个列表,然后用C/C++的方式对它进行处理,生成一个二维数组,最后再把这个数组以二维列表的形式返回给Python。我把代码简化了一下,以便更好地提问:

我希望c_Func能够完成这个过程,并且我可以顺利编译而没有错误。第二个函数是可以调用的,但显然它不工作。首先,我需要解决一个问题,就是列表不能直接替换为double*类型,其次是py_Func不能返回double*类型。那么我该如何修改这两个问题呢?

cdef double** c_Func(int dim,double* init_val):
    cdef double** frozen_ans= <double**> malloc(dim*sizeof(double))
    frozen_ans[0]=init_val
    return frozen_ans
def py_Func(int dim, double* init_val):
    return c_Func(dim,init_val)

1 个回答

2

我猜你想要处理来自C/C++的数据。

不要使用malloc,因为你之后无法释放那个指针,这样会导致内存泄漏。建议使用一些可以被Python处理的容器,比如numpy数组。

这里说的“处理”是指,当numpy数组被Python的垃圾回收器处理时,Python会自动帮你释放那块内存。

进一步说,使用numpy的方式,你可以在cython中创建一个连续的、类似C语言风格的numpy数组arr,然后通过它的地址&arr[0]在纯C代码中填充或使用它(只要它不是空的),最后将它作为Python的numpy.ndarray对象返回。你可以查看这个链接,了解如何方便地访问numpy对象。这种方式的一个很大优点是arr可以在C代码中像C数组一样使用。

在你的cython函数结束时,如果你不想返回一个numpy数组,可以使用arr.tolist()方法,但这样会有额外的开销,因为你是在创建一个新的列表。

关于输入部分,你提到你的函数必须接受一个Python列表。它可以:

  • 接受一个numpy数组,进行操作后返回。
  • 接受一个Python列表l,用np.ascontiguousarray(l)将其转换为numpy数组,进行操作后返回。在这种情况下,你会有复制的开销,但这没什么办法。

撰写回答