Я выполнил сериализацию для устройств защиты и сети, и я был бы рад поделиться своим опытом, поскольку вы предпочитаете двоичную сериализацию.
Я использую объединения для сериализации. Предположим, что у вас есть структура, которая содержит некоторые элементы, данные и указатели, и это содержит данные для члена семьи:
struct fam_member
{
char name [ MAX_NAME_LEN + 1 ];
int height;
age_bracket_t age_bracket;
fam_member_t* mother;
fam_member_t* father;
}fam_member_t;
Возрастная скобка - это перечисление:
typedef enum age_bracket
{
under_18 = 0 , from_18_to_25 = 1 , from_26_to_40 = 2 , over_40 = 3
}age_bracket_t;
Основная проблема и самая распространенная ошибка - это структурное заполнение, не относящееся к этому серьезно. Здесь - хорошее начало, если кто-то не знаком с этой проблемой.
Мое простое решение состоит в том, чтобы передавать данные от байта к байту (или бит к биту), делать то, что вам нужно делать с сериализованными данными (то есть отправлять их через сокет), и в конце десериализовать.
Я определяю союз следующим образом:
typedef union serialized_struct
{
fam_member_t family_member;
unsigned char data[ (MAX_NAME_LEN + 1 ) + (sizeof(int)*3) ];
}serialized_struct_t;
(Некоторые думают об объединении здесь)
Цель объединения - сохранить память, используя одну и ту же область памяти для хранения разных объектов в разное время. В этом примере это поможет нам и фактически бесплатно сериализует структуру семейных объектов.
Вот функция, которая сериализует массив членов семьи (если вы можете сделать область, одиночная будет просто куском. Вот почему я выбираю массив здесь).
int serialize_array(fam_member_t* people , char* message , int elements)
{
if((people == NULL ) || (message == NULL) || (elements < 1))
{
return -1;
}
int size = sizeof(fam_member_t);
int i;
for(i=0 ; i < elements ; i++)
{
serialized_struct_t x;
memcpy((x.family_member.name) , people[i].name , MAX_NAME_LEN);
x.family_member.age_bracket = people[i].age_bracket;
x.family_member.height = people[i].age_bracket
x.family_member.mother = people[i].mother;
x.family_member.father = people[i].father;
memcpy ( (message + (size * i)) , x.data , size );
}
return 0;
}
Здесь мы инициируем все данные каждого члена в структуре, которая находится в объединении. Сообщение содержит сериализованные данные. Это десериализованная функция, которая будет выполнять обратное действие
int desirialize_array(fam_member_t* people , char* message , int elements)
{
if((people == NULL ) || (message == NULL) || (elements < 1))
{
return -1;
}
int size = sizeof(fam_member_t);
serialized_struct_t y;
int i;
for (i =0 ; i < elements ; i ++ )
{
memcpy ( y.data , (message + (size * i)) , size );
memcpy ( people[i].name , y.family_member.name , MAX_NAME_LEN);
people[i].age_bracket = y.family_member.age_bracket;
people[i].height = y.family_member.height;
people[i].mother = y.family_member.mother;
people[i].father = y.family_member.father;
}
return 0;
}
Это сериализация и десериализация в примере c. Для вашего случая, когда вам нужно десериализовать это в python, я думаю, будет легко, если вы выясните, что будет средством сериализации. JSON, который, например, сказал Александр Толкачев, может быть решением.
Надеюсь, этот упрощенный пример поможет вам.