【问题标题】:Binary Serialization of multiple data types多种数据类型的二进制序列化
【发布时间】:2021-08-19 13:57:19
【问题描述】:

我正在尝试在 Visual Studio 中将具有多种数据类型的 C++ 结构序列化为二进制文件,并一次将它们全部反序列化。但是在读回数据时面临字符串内存分配的问题。我知道问题出在哪里,还有其他我可以使用的开源库,但我不想使用它们,除非确实有必要,而且我也知道我可以一个一个地写入/读取数据类型,但这种方法是对于包含大量数据类型的结构来说太长了。我想在不使用任何开源库的情况下一次性执行写/读操作。 下面是一个结构示例:

struct Frame {
    bool isPass{ true };
    uint64_t address{ 0 };
    uint32_t age{ 0 };
    float marks{ 0.0 };
    std::string userName;
};

有没有办法以二进制格式一次性执行写/读操作? 谢谢你

【问题讨论】:

  • 我强烈建议您使用开源库(boost 非常好),序列化充满了细微差别和陷阱。一旦你不处理琐碎的类型,你就有麻烦了。此外,即使是普通类型,您也会面临与大小 edian 的兼容性问题。
  • 简短的回答是否定的。
  • 所以 protobuf 或 boost::serialization 是我唯一的选择 ????,谢谢大家...

标签: c++ visual-c++ binary-serialization


【解决方案1】:

不使用现有的库永远都不好。还是……

例如,您可以创建一个创建纯虚拟类,例如

class Serializable
{
public:
    virtual std::vector<char> serialize() = 0;
}

然后:

  1. 您为自己拥有的所有类实现它
  2. 您在某个静态类中为您使用的所有 STL 和 PoD 类型(std::strings、PoD 类型和仅具有 PoD 类型的结构)实现序列化方法。基本上,在序列化过程中,您可以在其中放置类似 [size][type][data ~ [size][type][data][size][type][data]] 的内容。
  3. 然后,当您处理一个类进行序列化时,您创建一个缓冲区,首先将一个大小放入其中,然后键入标识符,然后放入所有由您在 1) 和 2) 中实现的序列化的成员的所有字节李>
  4. 当您从这样的数组中读取任何内容时,您会反向执行相同的操作:从数组中读取 N 个字节(第一个字段),确定其实际类型(第二个字段),读取所有成员,反序列化包含的所有内容。

这个过程是递归的。

但是……伙计,这真是个坏主意。使用 protobuf 或 boost::serialization。或其他任何东西 - 互联网上有很多序列化库。根据您的问题阅读这些珍贵的 cmets。人们是对的。

【讨论】:

    【解决方案2】:

    假设您有一些其他机制来跟踪您的帧大小,请将您的结构重写为:

    struct Frame {
        bool isPass{ true };
        uint8_t pad1[3]{};
        uint32_t age{ 0 };
        uint64_t address{ 0 };
        double marks{ 0.0 };
        char userName[];
    };
    

    如果我们有一个指针Frame* frame。我们可以使用write(fd, frame, frame_size) 来写这个。 (frame_size &gt; sizeof(frame))。

    假设您已将帧读入缓冲区,您可以使用以下方式访问数据: auto frame = reinterpret&lt;const Frame*&gt;(buf) 因此,userName 的长度将是 frame_size - sizeof(Frame)。您现在可以通过结构访问元素。

    它非常类似于 C,并且该方法仅限于数组末尾的一个可变长度元素。

    【讨论】:

    • 这也仅限于每个文件的单个元素。如果它总是相同的结构,你总是知道类型。但是如果里面有字符串,你还需要记住对象大小才能正确反序列化。
    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2016-09-15
    • 2015-11-19
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多