代码之家  ›  专栏  ›  技术社区  ›  Daniel Lucraft

在C中序列化数据结构

  •  41
  • Daniel Lucraft  · 技术社区  · 17 年前

    我想要一个C库,可以将我的数据结构序列化到磁盘,然后再载入它们。它应该接受任意嵌套的结构,可能带有循环引用。

    我认为这个工具需要一个描述我的数据结构的配置文件。允许库使用代码生成,尽管我很确定没有它也可以这样做。

    注意我对数据可移植性不感兴趣。我想用它作为缓存,这样我就可以相信环境不会改变。

    谢谢。


    结果

    有人建议 Tpl 这是一个非常棒的库,但是我相信它不做任意的对象图,比如每个节点都包含另外两个节点的节点树。

    另一个候选人是 Eet ,这是启蒙窗口管理器的一个项目。看起来很有趣,但是,同样,似乎没有序列化嵌套结构的能力。

    10 回复  |  直到 8 年前
        1
  •  16
  •   Robert Gamble    17 年前

    退房 tpl 。从概述来看:

    tpl是序列化c的库。 数据。数据存储在 自然二进制形式。API很小 试着“别挡道”。 与使用XML相比,TPL更快 更容易在C程序中使用。第三方物流 可以序列化许多C数据类型, 包括结构。

        2
  •  10
  •   dmckee --- ex-moderator kitten    17 年前

    我知道你要一个图书馆。如果你找不到一个:(Burg::,你会认为这是一个解决的问题!),下面是解决方案的大纲:

    您应该能够编写代码生成器[1]来序列化树/图,而无需(运行时)相当简单的预处理。

    您需要解析节点结构( typedef 处理?),并以直截了当的方式编写包含的数据值,但要小心对待指针。

    • 用于指向其他对象的指针(即 char *name; 你哪一个 知道 单独引用,可以直接序列化目标数据。

    • 对于可能被多重引用的对象和树的其他节点,您必须表示指针结构。每个对象都被分配一个序列号,这是代替指针写出的序列号。保持当前内存位置和序列化号之间的转换结构。当遇到一个指针时,看看它是否已经被分配了一个数字,如果没有,给它一个,并将该对象排队进行序列化。

    回读还需要一个节点-/内存位置转换步骤,而且可能更容易在两个过程中完成:使用指针槽中的节点号重新生成节点(坏指针,警告)以找出每个节点的位置,然后再次遍历结构以修复指针。

    我对第三方物流一无所知,但你也许可以依靠它。


    磁盘/网络格式可能应该用一些类型信息作为框架。你需要一个破坏名誉的计划。


    〔1〕 ROOT 使用此机制在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 ?

    在设计数据结构和/或为序列化过程提供特定于实例的智能时,您需要小心。

        3
  •  6
  •   Amith Chinthaka    12 年前

    这是我的解决办法。它使用我自己实现的malloc、free和mmap、munmap系统调用。遵循给定的示例代码。裁判: http://amscata.blogspot.com/2013/02/serialize-your-memory.html

    在我的方法中,我创建一个char数组作为自己的ram空间。然后有分配内存和释放内存的函数。在创建数据结构之后,通过使用 mmap ,我将char数组写入文件。

    每当你想把它加载回内存时,有一个函数 munmap 将数据结构再次放入char数组。因为它有指针的虚拟地址,所以可以重新使用数据结构。也就是说,你可以创建数据结构,保存它,加载它,再编辑它,然后再保存它。

        4
  •  4
  •   quinmars    17 年前

    你可以看一看 eet . 用于存储C数据类型(包括嵌套结构)的启蒙项目库。尽管启蒙计划的几乎所有lib都处于alpha之前的状态,eet已经发布。然而,我不确定它是否能处理循环引用。可能不是。

        5
  •  3
  •   plan9assembler    17 年前
        6
  •  3
  •   gngrwzrd    15 年前

    你应该去看看gwlib。序列化程序/反序列化程序是扩展的。还有大量的测试可供参考。 http://gwlib.com/

        7
  •  2
  •   Jonathan Leffler    17 年前

    我假设你说的是存储一个图形结构,如果不是,那么忽略…

    如果您存储一个图,我个人认为最好的方法是实现一个函数,将您的图转换为邻接矩阵。然后,您可以创建一个将邻接矩阵转换为图形数据结构的函数。

    这有三个好处(在您的申请中可能重要,也可能不重要):

    • 邻接矩阵是创建和存储图形的一种非常自然的方法。
    • 您可以创建邻接矩阵并将它们导入到应用程序中。
    • 您可以以有意义的方式存储和读取数据。

    我在一个cs项目中使用了这种方法,而且肯定是我将再次使用它的方式。

    你可以在这里阅读更多关于邻接矩阵的内容: http://en.wikipedia.org/wiki/Modified_adjacency_matrix

        8
  •  1
  •   Jeff Hammerbacher    14 年前

    另一个选择是 Avro C ,实现 Apache Avro 在C.

        9
  •  1
  •   Bernardo Ramos    8 年前

    下面是一个使用 Binn 图书馆(我的作品):

      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 *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);
    
        10
  •  0
  •   AndyL    16 年前

    理论上亚姆应该做你想做的事 http://code.google.com/p/yaml-cpp/

    如果对你有用,请告诉我。

    推荐文章