Я очень часто использую пакет struct
для анализа двоичных данных, взятых из структур C, но я несколько раз достигал пределов этого:
- , когда моя исходная структура дополняется32-битная архитектура, в то время как python установлен в 64-битном дистрибутиве
- , когда деревья структур используются
- , когда структуры содержат указатели (что также является проблемой 32 против 64 бит)
Поэтому я иногда получаю вручную свои данные, одно число за другим struct.unpack_from('<one element>', ...)
, но это действительно медленно!
Какой наилучший подход для решения этой проблемы, учитывая тот факт, что яЯ могу создать файл, который содержит для каждой переменной: имя, тип, размер и смещение ...
Было бы легко создать функцию, подобную struct.unpack()
, которая принимает такиепроизвольное описание?Или у вас есть альтернативное решение?
Вот пример кода C, который генерирует проблемный случай:
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
typedef struct {
uint32_t a;
uint8_t b;
float c;
} alpha_T;
typedef struct {
uint32_t a;
int32_t * b;
double c;
} beta_T;
typedef struct {
alpha_T a;
beta_T b;
} gamma_T;
typedef struct {
uint32_t a_a;
uint8_t a_b;
float a_c;
uint32_t b_a;
int32_t * b_b;
double b_c;
} zeta_T;
int main() {
gamma_T m;
size_t p = (size_t) & m;
printf("m.a.a @%ld\n", (size_t) &(m.a.a) - p);
printf("m.a.b @%ld\n", (size_t) &(m.a.b) - p);
printf("m.a.c @%ld\n", (size_t) &(m.a.c) - p);
printf("m.b.a @%ld\n", (size_t) &(m.b.a) - p);
printf("m.b.b @%ld\n", (size_t) &(m.b.b) - p);
printf("m.b.c @%ld\n", (size_t) &(m.b.c) - p);
zeta_T z;
size_t n = (size_t) & z;
printf("z.a_a @%ld\n", (size_t) &(z.a_a) - n);
printf("z.a_b @%ld\n", (size_t) &(z.a_b) - n);
printf("z.a_c @%ld\n", (size_t) &(z.a_c) - n);
printf("z.b_a @%ld\n", (size_t) &(z.b_a) - n);
printf("z.b_b @%ld\n", (size_t) &(z.b_b) - n);
printf("z.b_c @%ld\n", (size_t) &(z.b_c) - n);
}
Вывод этого:
m.a.a @0
m.a.b @4
m.a.c @8
m.b.a @16
m.b.b @24
m.b.c @32
z.a_a @0
z.a_b @4
z.a_c @8
z.b_a @12
z.b_b @16
z.b_c @24
Если я использую простой struct.Struct('IBfIpd')
, я пропускаю дополнительное заполнение между m.a.c
и m.b.a
, и мы можем увидеть разницу с сглаженным эквивалентом z.
Так что мое текущее решение для декодирования mba,подготовить предыдущую таблицу для m (с буквой типа) и использовать struct.unpack_from('I', 16, n)