#c #msgpack #messagepack
#c #msgpack #messagepack
Вопрос:
Я хотел бы написать приложение-сериализатор, которое будет кодировать любой тип структуры данных C в формат MessagePack. Все примеры, которые я видел, показывают кодирование известных структур, подобных этой, с использованием MPack:
// encode to memory buffer
char* data;
size_t size;
mpack_writer_t writer;
mpack_writer_init_growable(amp;writer, amp;data, amp;size);
// write the example on the msgpack homepage
mpack_start_map(amp;writer, 2);
mpack_write_cstr(amp;writer, "compact");
mpack_write_bool(amp;writer, true);
mpack_write_cstr(amp;writer, "schema");
mpack_write_uint(amp;writer, 0);
mpack_finish_map(amp;writer);
// finish writing
if (mpack_writer_destroy(amp;writer) != mpack_ok) {
fprintf(stderr, "An error occurred encoding the data!n");
return;
}
// use the data
do_something_with_data(data, size);
free(data);
Но чего бы я хотел, так это иметь возможность кодировать любую структуру данных C. Например, если бы у меня было следующее:
struct My_Struct{
int number1;
float number2;
char array[6];
};
struct My_Struct ms = {10, 4.44, "Hello"};
откуда мне программно знать, что первые 4 байта представляют собой int, чтобы я мог вызвать функцию mpack_write_int, чтобы начать упаковку int в формат messagepack?
Комментарии:
1. Вам нужно вызвать функцию записи для каждого элемента структуры вручную. C не предоставляет автоматизации для этого. Однако есть одна идея: Если вам нужно написать много из них, вы могли бы записать эти определения в текстовые файлы в некотором формате, а затем использовать язык сценариев, который генерировал бы определения структуры и функции кодирования / декодирования для вас. Возможно, такого рода инструменты уже существуют.
2. @user694733, я понимаю, что мне нужно будет вызвать функцию записи для массивов int, float и char, но откуда мне знать, что ms изначально содержит эти типы?
3. Единственный способ узнать это — проверить определение структуры вручную. В C нет метода для перечисления структуры во время выполнения. Итак, вам нужно будет написать функцию кодирования для каждого типа структуры отдельно, например
void encode_my_struct_with_mpack(mpack_writer_t * writer, struct My_Struct ms) { /* call mpack write functions here */ }
4. вы можете увидеть, как это реализовано в исходных текстах msgpack, потому что msgpack может кодировать пользовательские структуры и классы. смотрите примеры в
msgpack-c/blob/master/test/object.cpp
иmsgpack-c/blob/master/test/user_class.cpp