Vicenç Gascó Vicenç Gascó - 4 months ago 39
JSON Question

C++ JSON Serialization

Before asking, let me say that I have searched, but I am kinda new on C++ so I need some help with that.

I want a way to serialize and deserialize Objects to JSON, as automatic as possible.

For me, the ideal way is that if I call in an instance JSONSerialize() it returns an string with a JSON object that has all the public properties of the object as

"name_of_property": "value"
For those values that are primitives, it is straightforward, for objects it should try to call on each JSONSerialize() or ToString() or something like that to recursively serialize all the public properties.
For collections it should also behave correctly (just vectors/arrays will be ok).

Deserialize: Just make an instance of the given object (let's say a dog) and call
, and that should fill all the public properties, creating the needed objects in case that the properties are not primitives, or the needed collections.

An example should run like that:

Dog *d1 = new Dog();
d1->name = "myDog";

string serialized = d1->JSONSerialize();

Dog *d2 = new Dog();
std::cout << d2->name; // This will print "myDog"

Or like that:

Dog *d1 = new Dog();
d1->name = "myDog";

string serialized = JSONSerializer.Serialize(d1);

Dog *d2 = JSONSerializer.Deserialize(serialized, Dog);
std::cout << d2->name; // This will print "myDog"

Does anything, easy like that, exists?? THANKS :))


For that you need reflection in C/C++ language, that doesn't exists. You need to have some meta data describing the structure of your classes (members, inherited base classes). For the moment C/C++ compilers doesn't provide automatically that information in built binaries.

I had the same idea in mind, and I used GCC XML project to get this information. It outputs XML data describing class structures. I have built a project and I'm explaining some key points in this page :

Serialization is easy, but we have to deal with complex data structure implementations (std::string, std::map for example) that play with allocated buffers. Deserialization is more complex and you need to rebuild your object with all its members, plus references to vtables ... a painful implementation.

For example you can serialize like that :

    // Random class initialization
    com::class1* aObject = new com::class1();

    for (int i=0; i<10; i++){

    aObject->pdata = new char[7];
    for (int i=0; i<7; i++){
            aObject->pdata[i] = 7-i;
    // dictionary initialization
    cjson::dictionary aDict("./data/dictionary.xml");

    // json transformation
    std::string aJson = aDict.toJson<com::class1>(aObject);

    // print encoded class
    cout << aJson << std::endl ;

To deserialize data it works like that:

    // decode the object
    com::class1* aDecodedObject = aDict.fromJson<com::class1>(aJson);

    // modify data

    // json transformation
    aJson = aDict.toJson<com::class1>(aDecodedObject);

    // print encoded class
    cout << aJson << std::endl ;


>:~/cjson$ ./main
{"_index":54,"_inner":  {"_ident":"test","pi":3.141593},"_name":"first","com::class0::_type":"type","com::class0::data":[0,1,2,3,4,5,6,7,8,9],"com::classb::_ref":"ref","com::classm1::_type":"typem1","com::classm1::pdata":[7,6,5,4,3,2,1]}

Usually these implementations are compiler dependent (ABI Specification for example), and requires external description to work (GCCXML output), such are not really easy to integrate to projects.