Python — возвращение массива Cython

Как правильно инициализировать и вернуть массив 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.

В конце хочу позвонить cyTest из чистой функции C ++:

#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

Решение

Вы возвращаете ссылку на локальный массив (вывод), который не будет работать.

Попробуйте изменить ваш скрипт на:

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 );

Если вы хотите использовать cdef double* results = cyTest(test) в вашем скрипте Pyx, то не забудьте использовать PyMem_Free(results)

1

Другие решения


По вопросам рекламы [email protected]