Сериализация пакетов в С++

У меня есть проект, который выполняет сериализацию пакетов нескольких разных типов (Packet1, Packet2...). Все они расширяют класс PacketHeader и выполняют собственную сериализацию

Этот подход кажется очень грязным и подверженным ошибкам, особенно по мере роста количества полей.

Есть ли более чистый и более OOP и С++ способ для сериализации (без сторонней библиотеки)?

class PacketHeader {
 ******* type;
 ******** id;
 ******** seqNum;
 virtual void serialize(******* *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 {
 ******** payload;
 virtual void serialize(******* *buf, size_t size) {
 int offset = PacketHeader::size();
 PacketHeader::serialize(buf, size);
 memcpy(buf + offset, &n.payload, sizeof(n.payload));
 offset += sizeof(n.payload);
 }
}
1 ответ

Выполнение сериализации по структурам и классам с элементами данных требует, чтобы вы подавали информацию о смещении, размере и типе для каждого члена в сериализаторе. Это источник "беспорядочного" аспекта, и вы не можете избежать его независимо от того, насколько элегантен ваш дизайн.

Есть несколько вспомогательных библиотек, которые могут обеспечить некоторую структуру для этого, но они, как правило, просто синтаксические сладости, и их довольно сложно поддерживать по мере роста количества типов сообщений.

Вместо этого я бы рекомендовал посмотреть на системы, которые предоставляют словари - объекты данных ключа/значения, а не использовать собственные элементы данных структуры/класса С++. Некоторые используют стандартные форматы сериализации, такие как JSON. JSONCPP - очень хорошо оцененный пакет, который делает это: http://jsoncpp.sourceforge.net/

В основном они обеспечивают преимущество в том, что программная система будет лучше масштабироваться по мере ее роста и не станет экспоненциальной головной болью.

Если требуется бинарная сериализация, взгляните на BSON, MessagePack, Google Protocol Buffers и Apache Thrift. Все они предлагают библиотеки или привязки для С++.

licensed under cc by-sa 3.0 with attribution.