El módulo struct imita las estructuras en C. Se requieren más ciclos de CPU para que un procesador lea una palabra de 16 bits en una dirección impar o una dword de 32 bits en una dirección no divisible por 4, por lo que las estructuras agregan "bytes de pad" para hacer que los miembros de la estructura caigan en límites naturales. Considere:
struct { 11
char a;
short b; ------------
char c; axbbcxxxdddd
int d;
};
Esta estructura ocupará 12 bytes de memoria (siendo x bytes de pad).
Python funciona de manera similar (véase la documentación struct):
>>> import struct
>>> struct.pack('BHBL',1,2,3,4)
'\x01\x00\x02\x00\x03\x00\x00\x00\x04\x00\x00\x00'
>>> struct.calcsize('BHBL')
12
Los compiladores suelen tener una forma de eliminar el relleno. En Python, cualquiera de = <>! eliminará el relleno:
>>> struct.calcsize('=BHBL')
8
>>> struct.pack('=BHBL',1,2,3,4)
'\x01\x02\x00\x03\x04\x00\x00\x00'
Tenga cuidado con dejar que struct maneje el relleno. En C, estas estructuras:
struct A { struct B {
short a; int a;
char b; char b;
}; };
son típicamente 4 y 8 bytes, respectivamente. El relleno se produce al final de la estructura en caso de que las estructuras se utilicen en una matriz. Esto mantiene a los miembros 'a' alineados en los límites correctos para estructuras posteriores en el conjunto. módulo struct de Python no hace almohadilla al final:
>>> struct.pack('LB',1,2)
'\x01\x00\x00\x00\x02'
>>> struct.pack('LBLB',1,2,3,4)
'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04'
Lo que me pregunto es por qué Python no empaquetó los datos en ese formato en primer lugar. "01 01 00" empaquetó el byte 0x01, el corto 0x01, pero está tratando de descomprimirlo como "01 00 01 00". De todos modos, resolví mi problema, siempre estoy agregando '<' antes de todos mis códigos de formato, para que sean poco endian poco acolchados. Gracias por la explicación. :) –
tuvo un problema similar, el '=' ni '@' no resolvió ... usando el código que hice en mac en Windows – jokoon
@ThomasO ¿Por qué dices que está empaquetado como "01 01 00"? Estoy viendo struct.pack ('BH', 1, 2) == '\ x01 \ x00 \ x02 \ x00'. – aij