Apa solusi yang baik untuk serialisasi dalam C ++? [Tutup]

18

Saya ingin tahu solusi apa yang muncul dari pengembang game untuk membuat serial berbagai jenis data yang mereka tangani untuk game mereka. Apakah Anda menggunakan hierarki GameObject monolitik yang menampung antarmuka serialisasi untuk tipe turunan, menggunakan semacam solusi RTTI khusus, melakukan serialisasi stream eksplisit untuk kelas tertentu, atau menggunakan beberapa solusi open source (boost :: serialization, s11n, dll).

Tandai
sumber
1
Saya pikir serialisasi dalam pemrograman pengembangan game adalah topik penting, tapi saya tidak suka pertanyaan ini. Apa yang kamu coba lakukan? Apa masalah spesifik yang Anda coba selesaikan? Sebagai pengganti, saya mengonversikannya ke wiki komunitas sehingga lebih merupakan format diskusi.
Tetrad
Saya pikir akan lebih baik untuk menerapkan beberapa format untuk ini, (ala pertanyaan kontrol versi).
Jesse Dorsey

Jawaban:

9

Protokol buffer dari Google dapat menjadi pendekatan yang cukup bagus untuk membuat serialisasi objek c ++. Anda mungkin harus membuat beberapa objek perantara sebagai bagian dari proses serialisasi, tetapi juga berfungsi di banyak platform dan bahasa.

Ben Zeigler
sumber
1
Saya menggunakannya dan mudah jika Anda dapat mengotomatisasi pembuatan kode di sistem build Anda. Meskipun keuntungan yang sangat baik adalah memungkinkan Anda untuk mentransfer data pada mesin jarak jauh tanpa mempertimbangkan platform yang digunakan, dan itu dioptimalkan untuk itu sehingga objek yang dihasilkan tidak besar.
Klaim
10

Kami dalam game kami cukup menggunakan boost.serilization , mudah digunakan dan sangat cepat, tapi menurut saya hanya berguna untuk savegames. Jika Anda mencoba membuat karakter, saya sarankan Anda sesuatu yang berbasis XML'ish atau JSON, karena mudah dibaca dan diedit walaupun Anda tidak memiliki editor.

awildturtok
sumber
Saya telah melihat boost :: serialisasi berhasil digunakan untuk komunikasi klien / server juga. Namun, AFAIK berbasis aliran, jadi ini bukan versi toleran. Itu mungkin bukan pemecah kesepakatan untuk komunikasi klien / server, tetapi jika Anda menggunakannya untuk gim yang disimpan, maka setiap perubahan pada struktur data gim membuat pemuatan gim yang disimpan lebih lama menjadi tidak mungkin secara virtual (dukungan untuk memuat versi objek yang lebih lama menjadi tugas yang nyata ).
Mike Strobel
2
@ MikeStrobel Saya baru-baru ini meninjau beberapa serialisasi dan json kit dan menemukan komentar ini. boost :: serialisasi secara eksplisit mendukung versi. Panggilan bersambung dapat menerima nomor versi dan kemudian tergantung pada pengguna untuk menerapkan logika percabangan dasar (jika (versi> 1.0) ...). Secara keseluruhan sepertinya cukup kuat.
M2tM
Malu sepertinya tidak mendukung pengalokasi / deleter khusus.
JamesAMD
1
Saya baru saja porting dari meningkatkan serialisasi ke sereal. Pelabuhan itu sangat mulus . Itu bekerja seperti pesona. Sereal mendukung xml, json, biner, dan biner portabel . Alasan mengapa saya mengirim sereal adalah yang terakhir. Saya memerlukan arsip biner portabel karena saya menjalankan server yang terhubung dengan klien (untuk saat ini mac, segera iOS dan Android). Saya cukup senang dengan peningkatan serialisasi tetapi saya pikir beberapa fitur sereal mengambil langkah lebih jauh dengan cara yang lebih baik, seperti serialisasi biner portabel yang disebutkan. Untuk buffer protokol interop bahasa dan semacamnya lebih baik.
Germán Diago
Per docs boost.serialisasi tidak aman untuk thread. Sereal juga tidak menggunakan API serupa.
Hi-Angel
3

Saya lebih suka JSON untuk serialisasi. Sangat mudah untuk menguraikan dan ada perpustakaan gratis yang tersedia seperti http://jsoncpp.sourceforge.net/ Saya tidak pernah menjadi penggemar dorongan atau RTTI di C ++. Tinyxml juga berfungsi dengan baik untuk serialisasi dan deserialisasi xml. http://www.grinninglizard.com/tinyxml/ Pada akhirnya saya tidak ingin harus menghabiskan lebih banyak waktu daripada saya harus serialisasi.

Steven Behnke
sumber
2

Google FlatBuffers adalah perpustakaan serialisasi lintas platform yang efisien untuk C ++, dengan dukungan untuk Java dan Go. Itu dibuat di Google khusus untuk pengembangan game dan aplikasi penting lainnya.

Ini tersedia sebagai sumber terbuka di bawah lisensi Apache, v2.

Kimi
sumber
1

XDS dirancang hanya untuk tujuan ini, ini memberi Anda manfaat XML selama pengembangan dan manfaat representasi biner kompak pada waktu distribusi.

pengguna16
sumber
Saya tidak begitu yakin apa yang membuat XDS berbeda dari Google Protocol Buffer? Mereka tampaknya memiliki tujuan yang sama, kecuali bahwa XDS adalah yang pertama.
jacmoe
Anda pasti bermaksud XSD dan bukan XDS? codesynthesis.com/products/xsd Saya ingin memposting jawaban untuk menyelesaikan daftar.
v.oddou
1

Jika Anda menggunakan platform Linux, Anda dapat langsung menggunakan json.hperpustakaan untuk serialisasi. Berikut adalah contoh kode yang saya temui. Sumber: 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;
}
Philip Allgaier
sumber
0

Buffer jsonCpp dan Protokol adalah opsi yang baik. Setahu saya keduanya hanya akan memungkinkan Anda untuk struktur pohon serial di luar kotak (tolong perbaiki saya jika saya salah). boost :: serialisasi dapat menangani grafik yang berubah-ubah, tetapi tidak memiliki format teks yang bagus seperti json (saya pikir ada format xml)

Secara pribadi saya pikir pendekatan untuk serialisasi json yang telah diambil Dojo adalah yang terbaik
http://docs.dojocampus.org/dojox/json/ref

Saya membuat versi saya sendiri di c + + menggunakan jsoncpp, yang juga akan deserialize objek yang diketik (saya punya semacam pabrik besar untuk semua tipe saya). Ini memungkinkan saya untuk membuat heboh dari kumpulan file json yang bisa direferensikan, saya mohon.

Jonathan Fischoff
sumber