4

I have a project that does packet serialization of several different types(Packet1, Packet2...). They all extend a PacketHeader class and does its own serialization

This approach seems very messy and error-prone, especially as the number of fields grows.

Is there a cleaner and more OOP & C++ way for serialization(without 3rd-party library)?

class PacketHeader {
    uint8_t type;
    uint32_t id;
    uint32_t seqNum;

    virtual void serialize(uint8_t *buf, size_t size) {
        int offset = 0;
        PacketHeader n;
        n.type = type;
        n.id = htonl(id);
        n.seqNum = htonl(seqNum);
        memcpy(buf + offset, &(n.type), sizeof(n.type));
        offset += sizeof(n.type);
        memcpy(buf + offset, &(n.id), sizeof(n.id));
        offset += sizeof(n.id);
        memcpy(buf + offset, &n.seqNum, sizeof(n.seqNum));
        offset += sizeof(n.seqNum);
    }
}

class Packet1 : public PacketHeader {
    uint32_t payload;

    virtual void serialize(uint8_t *buf, size_t size) {
        int offset = PacketHeader::size();
        PacketHeader::serialize(buf, size);
        memcpy(buf + offset, &n.payload, sizeof(n.payload));
        offset += sizeof(n.payload);
    }
}
4

1 回答 1

2

对具有数据成员的结构和类进行本机序列化需要您将每个成员的偏移量、大小和类型信息提供给序列化程序。这就是“凌乱”方面的根源,无论您的设计多么优雅,您都无法避免它。

有一些帮助库可以为其提供一些结构,但它们通常只是语法糖果,随着消息类型数量的增加,仍然很难维护。

相反,我建议查看提供字典的系统——键/值数据对象——而不是使用本机 C++ 结构/类数据成员。有些使用标准的序列化格式,例如 JSON。JSONCPP 是一个非常受欢迎的包,它可以做到这一点:http: //jsoncpp.sourceforge.net/

大多数情况下,它们提供的优势是软件系统将随着它的增长而更好地扩展,并且不会成为指数级的维护难题。

如果需要二进制序列化,请查看 BSON、MessagePack、Google Protocol Buffers 和 Apache Thrift。它们都为 C++ 提供库或绑定。

于 2013-05-09T20:47:27.753 回答