extendiendo la matriz de variables c globales con swig y python
Frecuentes
Visto 552 equipos
3
Tengo una matriz de variables globales en c que me gustaría incorporar a python. Y estoy teniendo dificultades con varout
mapa de tipos:
/* example.c */
int foo[] = {0, 1};
Y aquí está la interfaz muy vainilla:
/* example.i */
%module example
%{
extern int foo[2];
%}
%typemap(varout) int foo[] {
int i;
//$1, $1_dim0, $1_dim1
$result = PyList_New($1_dim0);
for (i = 0; i < $1_dim0; i++) {
PyObject *o = PyInt_FromLong((double) $1[i]);
PyList_SetItem($result,i,o);
}
}
%include "example.c"
Cuando intento construirlo con el siguiente SConstruct:
import distutils.sysconfig
env = Environment(SWIGFLAGS='-python -shadow -Wall'.split(),
CPPPATH=[distutils.sysconfig.get_python_inc()],
SHLIBPREFIX="")
env.SharedLibrary('_example.so', ['example.c', 'example.i'])
$1_dim0
la variable especial no se completa, lo que da como resultado el siguiente código no compilable en example_wrap.c
:
SWIGINTERN PyObject *Swig_var_foo_get(void) {
PyObject *pyobj = 0;
{
int i;
//foo, , foo_dim1
pyobj = PyList_New();
for (i = 0; i < ; i++) {
PyObject *o = PyInt_FromLong((double) foo[i]);
PyList_SetItem(pyobj,i,o);
}
}
return pyobj;
}
Claramente, la coincidencia del mapa de tipos ha ocurrido, pero falta la dimensionalidad de la matriz. ¿Qué me estoy perdiendo? La codificación dura de la dimensión funciona.
En general, ¿existe alguna forma de extender la cvar
variables con trago?
$ swig -version
SWIG Version 2.0.4
Compiled with g++ [i686-pc-linux-gnu]
Configured options: +pcre
Please see http://www.swig.org for reporting bugs and further information
2 Respuestas
2
Ya casi estás allí con tu varout
mapa tipográfico. Necesitas hacer dos cambios menores:
Necesitas agregar el tamaño
ANY
En el correo electrónico “Su Cuenta de Usuario en su Nuevo Sistema XNUMXCX”.int foo[]
mapa de tipos:%typemap(varout) int foo[ANY] { int i; //$1, $1_dim0, $1_dim1 $result = PyList_New($1_dim0); for (i = 0; i < $1_dim0; i++) { PyObject *o = PyInt_FromLong((double) $1[i]); PyList_SetItem($result,i,o); } }
Esto asegura que su mapa de tipos coincida con matrices de (cualquier) tamaño conocido, no solo equivalente a
int *foo
.Necesita modificar example.c para hacer el tamaño de
foo
más claro Es C legal y correcto tal como está, pero es complicado deducir el tamaño de la matriz a menos que sea un compilador completo de C. Cambiándolo a:int foo[2] = {0, 1};
es suficiente para asegurarse de que coincide con el
varout
mapa tipográfico.
Con esos dos cambios, el código generado funciona como esperas:
SWIGINTERN PyObject *Swig_var_foo_get(void) {
PyObject *pyobj = 0;
{
int i;
//foo, 2, foo_dim1
pyobj = PyList_New(2);
for (i = 0; i < 2; i++) {
PyObject *o = PyInt_FromLong((double) foo[i]);
PyList_SetItem(pyobj,i,o);
}
}
return pyobj;
}
es lo que se genera en mi máquina con esos cambios.
Respondido 27 Jul 12, 22:07
0
Para aquellos como yo que reflexionan sobre qué hacer con matrices de tipos no simples, esta es una forma de hacerlo:
El tipo no simple:
typedef struct {
int a;
float b;
} Foo;
y una matriz global:
extern Foo *foov[40];
%typemap(varout) Foo *foov[ANY] {
int i;
$result = PyList_New($1_dim0);
for (i = 0; i < $1_dim0; i++) {
PyObject *o = SWIG_NewPointerObj($1[i], SWIGTYPE_p_Foo, 0);
PyList_SetItem($result, i, o);
}
}
Acabo de compartir esto porque me tomó una eternidad descubrirlo, y este artículo me ayudó. Solo necesitaba averiguar cómo asignar la versión SWIG de mi tipo no simple; lo encontré enterrado aquí:
Respondido el 20 de diciembre de 15 a las 16:12
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python arrays global-variables swig extend or haz tu propia pregunta.
Mostré cómo hacer que su ejemplo funcione, pero no tengo claro lo que quiso decir con: "En general, ¿hay alguna forma de extender las variables cvar globales con swig?" - ¿Hay algo más en eso que simplemente arreglar el mapa de tipos? - Flexo
Me preguntaba si puedo extender el
foo
tipo variable con__getitem__()
para hacerlo python scriptable con []. - Oleksiy¿No es una PyList ya subscriptable? - Flexo