Was sind gute Lösungen für die Serialisierung in C ++? [geschlossen]


18

Ich bin gespannt, welche Lösungen Spieleentwickler für die Serialisierung der verschiedenen Arten von Daten gefunden haben, mit denen sie sich für ihre Spiele befassen. Verwenden Sie eine monolithische GameObject-Hierarchie mit einer Serialisierungsschnittstelle für abgeleitete Typen, verwenden Sie eine Art benutzerdefinierte RTTI-basierte Lösung, führen Sie eine explizite Stream-Serialisierung für bestimmte Klassen durch, oder verwenden Sie einige Open-Source-Lösungen (boost :: serialization, s11n, etc).


1
Ich denke, Serialisierung in der Spieleentwicklung ist ein wichtiges Thema, aber ich mag diese Frage nicht. Was versuchst du zu tun? Welche spezifischen Probleme versuchen Sie zu lösen? Stattdessen habe ich es in ein Community-Wiki konvertiert, damit es eher ein Diskussionsformat ist.
Tetrad

Ich denke, es wäre gut, etwas Formatierung darauf anzuwenden (ua die Frage der Versionskontrolle).
Jesse Dorsey

Antworten:


9

Protokollpuffer von Google können ein guter Ansatz für die Serialisierung von C ++ - Objekten sein. Möglicherweise müssen Sie im Rahmen des Serialisierungsprozesses einige zwischengeschaltete Objekte erstellen, aber es funktioniert auch auf vielen Plattformen und in vielen Sprachen.


1
Ich benutze es und es ist einfach, wenn Sie die Codegenerierung in Ihrem Build-System automatisieren können. Obwohl ein wirklich hervorragender Vorteil darin besteht, dass Sie Daten auf entfernten Maschinen übertragen können, ohne auf die verwendete Plattform Rücksicht zu nehmen, und dass es dafür optimiert ist, damit die generierten Objekte nicht groß werden.
Klaim 08.10.10

10

Wir in unserem Spiel benutzen einfach boost.serilization , es ist einfach zu benutzen und sehr schnell, aber meiner Meinung nach ist es nur nützlich für Savegames. Wenn Sie versuchen, Zeichen zu erstellen, empfehle ich Ihnen XML'ish- oder JSON-basierte Dinge, da diese leicht zu lesen und zu bearbeiten sind, auch wenn Sie nicht über den Editor verfügen.


Ich habe gesehen, dass boost :: serialization auch erfolgreich für die Client / Server-Kommunikation eingesetzt wird. AFAIK ist jedoch streambasiert und daher nicht genau versionstolerant. Das ist zwar kein Deal-Breaker für die Client / Server-Kommunikation, aber wenn Sie es für gespeicherte Spiele verwenden, macht jede Änderung der Spieldatenstrukturen das Laden älterer gespeicherter Spiele zu einer virtuellen Unmöglichkeit (das Laden älterer Objektversionen wird zu einer echten Aufgabe ).
Mike Strobel

2
@MikeStrobel Ich habe kürzlich einige Serialisierungs- und JSON-Kits überprüft und bin auf diesen Kommentar gestoßen. boost :: serialization unterstützt explizit die Versionierung. Die Serialisierungsaufrufe können eine Versionsnummer erhalten, und dann muss der Benutzer die grundlegende Verzweigungslogik implementieren (if (version> 1.0) ...). Insgesamt scheint ziemlich robust.
24.12.2013

Schade, dass es keinen benutzerdefinierten Allokator / Deleter unterstützt.
JamesAMD

1
Ich habe gerade von Boost-Serialisierung auf Getreide portiert. Der Hafen war bemerkenswert glatt . Es wirkte wie ein Zauber. Cereal unterstützt XML, JSON, Binary und Portable Binary . Der Grund, warum ich auf Müsli portiert habe, war der letzte. Ich brauchte tragbare Binärarchive, da ich einen Server verwende, mit dem sich Clients (vorerst ein Mac, bald iOS und Android) verbinden. Ich war ziemlich zufrieden mit der Boost-Serialisierung, aber ich denke, einige der Funktionen von Getreide gehen noch einen Schritt weiter, wie beispielsweise die erwähnte portable binäre Serialisierung. Für Sprachinterop-Protokollpuffer und dergleichen ist es besser.
Germán Diago

Laut Dokumentation ist boost.serialization nicht threadsicher. Genauso wenig wie Cereal , das eine ähnliche API verwendet.
Hi-Angel


2

Google FlatBuffers ist eine effiziente plattformübergreifende Serialisierungsbibliothek für C ++ mit Unterstützung für Java und Go. Es wurde bei Google speziell für die Spieleentwicklung und andere leistungskritische Anwendungen entwickelt.

Es ist als Open Source unter der Apache-Lizenz v2 verfügbar.



1

XDS wurde speziell für diesen Zweck entwickelt und bietet Ihnen die Vorteile von XML während der Entwicklung und die Vorteile einer kompakten Binärdarstellung zum Zeitpunkt der Verteilung.


Ich bin mir nicht sicher, was XDS von Google Protocol Buffers unterscheidet. Sie scheinen den gleichen Zweck zu erfüllen, außer dass XDS der erste war.
Jacmoe

Du meinst doch XSD und nicht XDS? codesynthesis.com/products/xsd Ich wollte eine Antwort darüber posten, um die Liste zu vervollständigen.
v.oddou

1

Wenn Sie auf einer Linux-Plattform arbeiten, können Sie die json.hBibliothek direkt für die Serialisierung verwenden. Hier ist ein Beispielcode, auf den ich gestoßen bin. Quelle: 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

Sowohl der jsonCpp- als auch der Protokollpuffer sind gute Optionen. Meines Wissens nach können Sie in beiden Fällen nur standardmäßige Serienbaumstrukturen erstellen (bitte korrigieren Sie mich, wenn ich mich irre). boost :: serialization kann mit beliebigen Grafiken umgehen, hat aber kein nettes Textformat wie json (ich denke, es gibt ein xml-Format)

Persönlich denke ich, dass der Ansatz für die Json-Serialisierung, den Dojo gewählt hat, der beste ist
http://docs.dojocampus.org/dojox/json/ref

Ich habe meine eigene Version davon in c ++ mit jsoncpp erstellt, die auch typisierte Objekte deserialisiert (ich habe eine Art große Fabrik für alle meine Typen). Es ermöglicht mir, eine Szene aus einer Sammlung von JSON-Dateien zu erstellen, auf die ich trotzdem verweisen kann.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.