返回Cython数组

1 投票
1 回答
1347 浏览
提问于 2025-04-18 16:33

如何正确地初始化并返回一个Cython数组呢?比如说:

cdef public double* cyTest(double[] input):
  cdef double output[3]

  for i in xrange(3):
    output[i] = input[i]**2
    print 'loop: ' + str(output[i])
  return output

cdef double* test = [1,2,3]
cdef double* results = cyTest(test)

for i in xrange(3):
  print 'return: ' + str(results[i])

这样做会返回:

loop: 1.0->1.0
loop: 2.0->4.0
loop: 3.0->9.0
return: 1.88706086937e-299
return: 9.7051011575e+236
return: 1.88706086795e-299

所以很明显,results 仍然只指向一些无效的内容,而不是它应该指向的值。老实说,我对指针和数组的语法有点混淆,不太清楚在Cython中哪种更好或者更可行。

最后,我想从一个纯C++函数中调用 cyTest

#include <iostream>
#include <Python.h>
#include "cyTest.h"

void main() {
  Py_Initialize();
  initcyTest();
  double input[3] = {1,2,3};
  double* output = cyTest(input);

  for(int i = 0; i < 3; i++)
    std::cout << "cout: " << output[i] << std::endl;

  Py_Finalize();
}

这样做也会返回类似的结果:

loop: 1.0->1.0
loop: 2.0->4.0
loop: 3.0->9.0
cout: 1
cout: 6.30058e+077
cout: 6.39301e-308

有没有人能解释一下我犯了什么错误?我希望尽量简单一点。毕竟这只是从Cython返回一个数组到C++。如果不必要,我稍后再处理动态内存分配的问题。

1 个回答

1

你返回的是一个指向局部数组(output)的引用,这样是行不通的。

试着把你的脚本改成:

from cpython.mem cimport PyMem_Malloc

cdef public double * cyTest(double[] input):
    cdef double * output = < double * >PyMem_Malloc( sizeof(double) * 3 )
    for i in xrange(3):
        output[i] = input[i]**2
        print 'loop: ' + str(output[i])
    return output

然后在你的C++代码中,

在你用完double* output之后,记得用free( output );来释放内存。

如果你想在你的pyx脚本中使用cdef double* results = cyTest(test),那么别忘了用PyMem_Free(results)来释放内存。

撰写回答