Мне нужна библиотека C, которая может сериализовать мои структуры данных на диск, а затем загрузить их позже. Он должен принимать произвольно вложенные структуры, возможно, с циклическими ссылками.
Я предполагаю, что этому инструменту потребуется файл конфигурации, описывающий мои структуры данных. Библиотеке разрешено использовать генерацию кода, хотя я уверен, что без нее можно обойтись.
Обратите внимание: меня не интересует переносимость данных. Я бы хотел использовать его в качестве кеша, чтобы можно было полагаться на то, что окружающая среда не меняется.
Спасибо.
Полученные результаты
Кто-то предложил Tpl, отличную библиотеку, но я считаю, что она не создает произвольных графов объектов, таких как дерево узлов, каждый из которых содержит два других узла.
Другой кандидат - Восточноевропейское время, проект оконного менеджера Enlightenment. Выглядит интересно, но, опять же, не имеет возможности сериализовать вложенные структуры.





Проверьте tpl. Из обзора:
Tpl is a library for serializing C data. The data is stored in its natural binary form. The API is small and tries to stay "out of the way". Compared to using XML, tpl is faster and easier to use in C programs. Tpl can serialize many C data types, including structures.
Еще одна проблема с tpl - ограниченная переносимость поплавков.
Я предполагаю, что вы говорите о хранении структуры графа, если не игнорировать ...
Если вы храните график, я лично считаю, что лучшей идеей было бы реализовать функцию, которая преобразует ваш график в матрицу смежности. Затем вы можете создать функцию, которая преобразует матрицу смежности в структуру данных вашего графа.
Это дает три преимущества (которые могут иметь или не иметь значения для вашего приложения):
Я использовал этот метод во время проекта CS, и я определенно сделаю это снова.
Вы можете узнать больше о матрице смежности здесь: http://en.wikipedia.org/wiki/Modified_adjacency_matrix
Я не говорю о структуре графа в этом смысле. Мои структуры больше похожи на дерево, хотя я не хочу исключать циклические ссылки. Нет причин, по которым библиотека C не может сериализовать это без какой-либо обработки от моего имени.
Дерево - это просто частный случай графа, и, имея круговые ссылки, можно утверждать, что на самом деле у вас есть граф, а не дерево.
Хорошо: все структуры данных C можно рассматривать как графики памяти. Есть ли библиотека, которая может сериализовать эти данные?
Я знаю, вы просите библиотеку. Если вы не можете его найти (:: boggle ::, вы думаете, что проблема решена!), Вот схема решения:
Вы должны иметь возможность написать генератор кода [1] для довольно простой сериализации деревьев / графиков без предварительной обработки (во время выполнения).
Вам нужно будет проанализировать структуру узла (обработка typedef?) И записать включенные значения данных напрямую, но относитесь к указателям с некоторой осторожностью.
Для указателя на другие объекты (например, char *name;), на которые вы ссылаетесь знать по отдельности, вы можете сериализовать целевые данные напрямую.
Для объектов, на которые можно ссылаться несколько раз, и для других узлов вашего дерева вам нужно будет представить структуру указателя. Каждому объекту присваивается номер сериализации, который записывается вместо указателя. Поддерживайте структуру перевода между текущей позицией в памяти и номером сериализации. При обнаружении указателя проверьте, не присвоен ли ему уже номер, если нет, дайте ему его и поставьте этот объект в очередь для сериализации.
Для обратного чтения также требуется этап преобразования node - # / memory-location, и его может быть проще выполнить за два прохода: регенерировать узлы с номерами узлов в слотах указателя (плохой указатель, будьте осторожны), чтобы узнать, где каждый узел получает положите, затем снова пройдитесь по конструкции, фиксируя указатели.
Я ничего не знаю о tpl, но вы могли бы воспользоваться этим.
Формат на диске / в сети, вероятно, должен содержать некоторую информацию о типе. Вам понадобится схема изменения имен.
[1] КОРЕНЬ использует этот механизм для обеспечения очень гибкой поддержки сериализации в C++.
Позднее добавление: Мне приходит в голову, что это не всегда так просто, как я предполагал выше. Рассмотрим следующее (надуманное и плохо спроектированное) объявление:
enum {
mask_none = 0x00,
mask_something = 0x01,
mask_another = 0x02,
/* ... */
mask_all = 0xff
};
typedef struct mask_map {
int mask_val;
char *mask_name;
} mask_map_t;
mask_map_t mask_list[] = {
{mask_something, "mask_something"},
{mask_another, "mask_another"},
/* ... */
};
struct saved_setup {
char* name;
/* various configuration data */
char* mask_name;
/* ... */
};
и предположим, что мы инициализируем элементы struct saved_setup, так что mask_name указывает на mask_list[foo].mask_name.
Когда мы переходим к сериализации данных, что нам делать с struct saved_setup.mask_name?
Вам нужно будет позаботиться о проектировании своих структур данных и / или привнести в процесс сериализации некоторую аналитическую информацию для конкретного случая.
Спасибо за отличную запись. По сути, этот план был у меня в голове как «доказательство существования» библиотеки. Теоретически каждая библиотека, которую можно представить на C, была написана. Не могу поверить, что этого не существует. Я могу попробовать написать эту вещь на Рождество.
Вы можете посмотреть восточноевропейское время. Библиотека проекта просвещения для хранения типов данных C (включая вложенные структуры). Хотя почти все библиотеки проекта enlightenment находятся в пре-альфа-состоянии, eet уже выпущен. Однако я не уверен, может ли он обрабатывать циклические ссылки. Возможно нет.
HTH
Ссылка не работает.
Работает сейчас. Заголовок "libc11n: библиотека / фреймворк сериализации для C", sf ссылка: sourceforge.net/projects/s11n
Теоретически YAML должен делать то, что вы хотите http://code.google.com/p/yaml-cpp/
Пожалуйста, дайте мне знать, работает ли это для вас.
Правда. Однако YAML C++ сериализует структуры данных C, несмотря на то, что для этого требуется компилятор C++. Другие читатели SO могут найти это полезным.
вам следует проверить gwlib. сериализатор / десериализатор обширен. и есть обширные тесты, на которые можно посмотреть. http://gwlib.com/
Другой вариант - Avro C, реализация Apache Avro в C.
Это мое решение. Он использует мою собственную реализацию системных вызовов malloc, free и mmap, munmap. Следуйте приведенным примерам кодов. Ссылка: http://amscata.blogspot.com/2013/02/serialize-your-memory.html
В моем подходе я создаю массив символов как свое собственное пространство ОЗУ. Затем есть функции для выделения и освобождения памяти. После создания структуры данных с помощью mmap я записываю массив символов в файл.
Всякий раз, когда вы хотите загрузить его обратно в память, существует функция, которая использует munmap, чтобы снова поместить структуру данных в массив символов. Поскольку он имеет виртуальные адреса для ваших указателей, вы можете повторно использовать свою структуру данных. Это означает, что вы можете создать структуру данных, сохранить ее, загрузить, снова отредактировать и снова сохранить.
Это работало очень хорошо даже для вложенных древовидных структур, хотя для его компиляции потребовались некоторые изменения в коде. Отсутствует include для time.h и предполагаемый typedef для ushort, который не является стандартом языка.
Однако он не обрабатывает массивы указателей, поэтому структура графа, содержащая их, не сериализуется правильно, сериализуется только первый указатель.
Вот пример использования библиотеки Бинн (мое творение):
binn *obj;
// create a new object
obj = binn_object();
// add values to it
binn_object_set_int32(obj, "id", 123);
binn_object_set_str(obj, "name", "Samsung Galaxy Charger");
binn_object_set_double(obj, "price", 12.50);
binn_object_set_blob(obj, "picture", picptr, piclen);
// send over the network
send(sock, binn_ptr(obj), binn_size(obj));
// release the buffer
binn_free(obj);
Если вы не хотите использовать строки в качестве ключей, вы можете использовать binn_map, который использует целые числа в качестве ключей.
Также есть поддержка списков, и все эти структуры могут быть вложенными:
binn *list;
// create a new list
list = binn_list();
// add values to it
binn_list_add_int32(list, 123);
binn_list_add_double(list, 2.50);
// add the list to the object
binn_object_set_list(obj, "items", list);
// or add the object to the list
binn_list_add_object(list, obj);
Tpl, похоже, не поддерживает вложенные структуры. Например, узел, который может содержать два подузла.