Python / SWIG: Salida de una matriz

Estoy intentando generar una matriz de valores desde una función C envuelta con SWIG para Python. Lo que estoy tratando de hacer es usar el siguiente mapa de tipos.

Pseudo código:

int oldmain() { float *output = {0,1}; return output; } 

Mapa de tipo:

 %typemap(out) float* { int i; $result = PyList_New($1_dim0); for (i = 0; i < $1_dim0; i++) { PyObject *o = PyFloat_FromDouble((double) $1[i]); PyList_SetItem($result,i,o); } } 

Mi código se comstack bien, pero se bloquea cuando ejecuto el acceso a esta función (sin más formas de depurarlo).

¿Alguna sugerencia sobre dónde voy mal?

Gracias.

Esto debería ponerte en marcha:

 /* example.c */ float * oldmain() { static float output[] = {0.,1.}; return output; } 

Usted está devolviendo un puntero aquí, y swig no tiene idea de su tamaño. El simple $ 1_dim0 no funcionaría, por lo que tendría que codificar o hacer alguna otra magia. Algo como esto:

 /* example.i */ %module example %{ /* Put header files here or function declarations like below */ extern float * oldmain(); %} %typemap(out) float* oldmain { int i; //$1, $1_dim0, $1_dim1 $result = PyList_New(2); for (i = 0; i < 2; i++) { PyObject *o = PyFloat_FromDouble((double) $1[i]); PyList_SetItem($result,i,o); } } %include "example.c" 

Entonces en python deberías obtener:

 >> import example >> example.oldmain() [0.0, 1.0] 

Al agregar typemaps puede encontrar muy útil -debug-tmsearch , es decir

 swig -python -debug-tmsearch example.i 

Debería indicar claramente que su mapa de tipos se utiliza cuando se busca un mapa de tipos "fuera" adecuado para float *oldmain Además, si solo desea acceder a la matriz variable global c, puede hacer el mismo truco usando typemap para varout lugar de solo out .

La forma más fácil de permitir que la longitud varíe es agregar otro parámetro de salida que también le indique el tamaño de la matriz:

 %module test %include  %typemap(in,numinputs=0,noblock=1) size_t *len { size_t templen; $1 = &templen; } %typemap(out) float* oldmain { int i; $result = PyList_New(templen); for (i = 0; i < templen; i++) { PyObject *o = PyFloat_FromDouble((double)$1[i]); PyList_SetItem($result,i,o); } } %inline %{ float *oldmain(size_t *len) { static float output[] = {0.f, 1.f, 2, 3, 4}; *len = sizeof output/sizeof *output; return output; } %} 

Esto se modifica desde esta respuesta para agregar size_t *len que se puede usar para devolver la longitud de la matriz en el tiempo de ejecución. Sin embargo, el mapa de tipo oculta completamente esa salida del envoltorio de Python y, en su lugar, lo utiliza en el %typemap(out) lugar de un tamaño fijo para controlar la longitud de la lista devuelta.