[SemiOT]Pack y unpack

Francesc Alted falted en pytables.org
Vie Oct 1 09:54:34 CEST 2004


A Dijous 30 Setembre 2004 23:36, Fernando Blat va escriure:
> Muchas gracias, es justo lo que quería. Lo he probado y funciona perfecto.

Pues no sé como ha sido, pues me he dado cuenta que en mi receta te dije que
usaras una definición como:

typedef struct {int *i; char *s; float *f;} pstruct;

cuando en realidad deberia ser algo como:

typedef struct {int i; char s[N]; float f;} pstruct;

en fin, supongo que ya te habrás dado cuenta.

> Sin embargo me he dado cuenta de que esta forma de compartir estructuras
> de datos entre C y Python está un poco cogida por pinzas, pues binarizar
> unos datos depende demasiado del compilador y de la plataforma. Si se quiere
> ser purista del todo sólo queda como solución enviar strings que luego se
> irán convirtiendo, según un orden dado, en los campos de la estructura de
> datos. De todas formas me gustaría conocer vuestras alternativas, ya como
> curiosidad, pues el problema está solucionado :)

Bueno, si se quiere ser purista y hacer código *eficiente* al mismo tiempo,
entonces puedes pasar la información usando una ordenación de bytes
determinada. La más típica para pasar información a través de la red es la
big-endian o también llamada network (la de los procesadores Intel es
little-endian). Puedes generarla usando el carácter '!' al principio del
formato struct. Con esto además el alienamiento de los datos es standard,
i.e. no hay 'huecos' entre los diferentes campos (cosa que muchos
compiladores introducen para conseguir mayores eficiencias de acceso a los
datos).

Una vez tengas el buffer en la máquina remota tienes que hacer dos cosas:

1.- Comprobar que byteorder tiene la máquina receptora. Esto es fácil:

     char byteorder[7];
     int n = 1;
     char *p = (char *) &n;
     if (*p == 1)
       strcpy(byteorder, "little");
     else
       strcpy(byteorder, "big");

    y después, si tu máquina es "little", simplemente le das la vuelta a los
    bytes para convertir los datos de "big" a "little".

2.- Creas una estructura que mapee los datos a recibir de manera que no haya
    "huecos" (i.e. sin alienamiento) entre ellos. Esto ya es poco más
    difícil, pero te puede servir cómo lo hace Python: mira el fichero
    Module/structmodule.c (te recomiendo el de la versión 2.4 que, aunque
    esté en alpha, han rehecho el código y parece más elegante que el de
    versiones anteriores). Presta particular atención a las rutinas align y
    calcsize.

Aunque si la velocidad no es importante, lo mismo te va a dar pasarlo todo
como cadenas. En fin, tú mismo.

-- 
Francesc Alted




Más información sobre la lista de distribución Python-es