Какие хорошие решения для сериализации в C ++? [закрыто]


18

Мне любопытно, какие решения разработчики игр придумали для сериализации различных типов данных, с которыми они имеют дело для своих игр. Ребята, вы используете какую-то монолитную иерархию GameObject, которая содержит интерфейс сериализации для производных типов, используете своего рода решение на основе RTTI, выполняете явную сериализацию потока для определенных классов или используете некоторые решения с открытым исходным кодом (boost :: serialization, s11n, и т.д).


1
Я думаю, что сериализация в программировании разработки игр - важная тема, но мне не нравится этот вопрос. Что ты пытаешься сделать? Какие конкретные проблемы вы пытаетесь решить? Вместо этого я преобразовал это в вики сообщества, так что это скорее формат обсуждения.
— Тетрад

Я думаю, что было бы хорошо, чтобы применить некоторые форматирования для этого (аля вопрос контроля версий).
— Джесси Дорси

Ответы:


9

Буферы протокола от Google могут быть очень хорошим подходом для сериализации объектов c ++. Возможно, вам придется создать некоторые промежуточные объекты как часть процесса сериализации, но он также работает на многих платформах и языках.


1
Я использую его, и это легко, если вы можете автоматизировать генерацию кода в вашей системе сборки. Хотя действительно превосходным преимуществом является то, что он позволяет передавать данные на удаленные машины без учета используемой платформы, и он оптимизирован для этого, поэтому сгенерированные объекты невелики.
— Klaim 8.10.10

10

Мы в нашей игре просто используем boost.serilization , она проста в использовании и очень быстра, но, на мой взгляд, просто полезна для сохранения игр. Если вы пытаетесь создавать символы, я рекомендую вам что-нибудь на XML'е или на основе JSON, потому что они легко читаются и редактируются, даже если у вас нет редактора.


Я видел, что boost :: serialization также успешно используется для связи клиент-сервер. Тем не менее, AFAIK основывается на потоке, поэтому он не совсем устойчив к версии. Возможно, это не нарушает соглашения о взаимодействии клиент / сервер, но если вы используете его для сохраненных игр, то любое изменение структуры игровых данных делает загрузку старых сохраненных игр виртуальной невозможностью (поддержка загрузки более старых версий объектов становится настоящей рутиной). ).
— Майк Штробель

2
@MikeStrobel Недавно я просматривал несколько сериализаций и наборов json и наткнулся на этот комментарий. boost :: serialization явно поддерживает управление версиями. Сериализованные вызовы могут получить номер версии, а затем пользователь может реализовать базовую логику ветвления (если (версия> 1.0) ...). В целом кажется довольно надежным.
— M2tM

Позор, кажется, не поддерживает пользовательский распределитель / удаление.
— JamesAMD

1
Я только что портировал с повышения сериализации на зерновые. Порт был удивительно гладким . Оно работало завораживающе. Cereal поддерживает xml, json, двоичный и переносимый двоичные файлы . Причина, по которой я портировал зерновые, была последней. Мне нужны были переносимые двоичные архивы, потому что я запускаю сервер, к которому подключаются клиенты (сейчас Mac, скоро iOS и Android). Я был очень доволен ускоренной сериализацией, но я думаю, что некоторые функции зерновых делают его еще лучше, например, упомянутая портативная двоичная сериализация. Для буферов протокола взаимодействия языков и так лучше.
— Герман Диаго

Согласно документам boost.serialization не является потокобезопасным. Также Cereal не использует аналогичный API.
— Привет, Ангел,

3

Мне скорее нравится JSON для сериализации. Это довольно просто разобрать, и есть бесплатные библиотеки, такие как http://jsoncpp.sourceforge.net/ Я никогда не был фанатом boost или RTTI в C ++. Tinyxml также хорошо работает для сериализации и десериализации xml. http://www.grinninglizard.com/tinyxml/ В конечном счете, я не хочу тратить больше времени, чем на сериализацию.


2

Google FlatBuffers - это эффективная кроссплатформенная библиотека сериализации для C ++ с поддержкой Java и Go. Он был создан в Google специально для разработки игр и других приложений, критичных к производительности.

Он доступен как открытый исходный код под лицензией Apache, v2.



1

XDS был разработан специально для этой цели, он дает вам преимущества XML во время разработки и преимущества компактного двоичного представления во время распространения.


Я не совсем уверен, что отличает XDS от буферов протокола Google? Кажется, они служат той же цели, за исключением того, что XDS был первым.
— Жакмо

Вы наверняка имеете в виду XSD, а не XDS? codesynthesis.com/products/xsd Я хотел опубликовать ответ об этом, чтобы завершить список.
— v.oddou

1

Если вы работаете на платформе Linux, вы можете напрямую использовать json.hбиблиотеку для сериализации. Вот пример кода, с которым я столкнулся. Источник: Json Serializer

//============================================================================
// Name        : JsonTest.cpp
// Author      : Manis Kumar Khedawat
//============================================================================

#include <iostream>
#include <json/json.h>

using namespace std;

struct objStruct{
    string str;
    int n1;
    int n2;
};

typedef objStruct obj;

void serializeToJson(json_object *jObj,obj* pObj)
{
    /*
    string str;
    int n1;
    int n2;
    */

    // Create json object for every member in struct Obj.

    json_object *jstr = json_object_new_string (pObj->str.c_str());
    json_object *jn1 =json_object_new_int(pObj->n1);
    json_object *jn2 =json_object_new_int(pObj->n2);

    // Add all above created object into jObj

    json_object_object_add(jObj,"str",jstr);
    json_object_object_add(jObj,"n1",jn1);
    json_object_object_add(jObj,"n2",jn2);

    // pObj is Serialzed into jObj
}

void deSerializeToJson(json_object *jObj,obj* pObj)
{
    /*
    string str;
    int n1;
    int n2;
    */

    // Get every member as different json obj from jObj
    json_object *jstr = json_object_object_get (jObj,"str");
    json_object *jn1 =json_object_object_get(jObj,"n1");
    json_object *jn2 =json_object_object_get(jObj,"n2");

    pObj->str=json_object_get_string(jstr);
    pObj->n1=json_object_get_int(jn1);
    pObj->n2=json_object_get_int(jn2);

    // jObj is DeSerialzed into pObj
}

int main() {
    // Lets Create an Object which we will serialze into Json
    obj obj1;
    obj1.n1=3;
    obj1.n2=6;
    obj1.str="This is String";

    // Create a json Object
    json_object* jObj=json_object_new_object();

    // To serialize into Json Object
    // Please Keep in mind , we are passing address of object (pointer) & not object
    serializeToJson(jObj,&obj1);

    obj obj2;
    // To serialize into Json Object
    // Please Keep in mind , we are passing address of object (pointer) & not object
    deSerializeToJson(jObj,&obj2);

    cout<<"String str == "<<obj2.str<<endl;
    cout<<"n1 & n2 : "<<obj2.n1<<" "<<obj2.n2<<endl;

    return 0;
}

0

И jsonCpp, и буфер протокола являются хорошими вариантами. Насколько мне известно, оба позволят вам создавать последовательные древовидные структуры из коробки (пожалуйста, исправьте меня, если я ошибаюсь). boost :: serialization может обрабатывать произвольные графы, но не имеет хорошего текстового формата, такого как json (я думаю, что существует формат xml)

Лично я думаю, что подход для сериализации json, который использовал Dojo, является лучшим
http://docs.dojocampus.org/dojox/json/ref

Я сделал свою собственную версию на c ++ с использованием jsoncpp, которая также будет десериализовать типизированные объекты (у меня есть своего рода большая фабрика для всех моих типов). Это позволяет мне сделать сцену из коллекции json-файлов, на которые можно ссылаться в любом случае, пожалуйста.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.