Konvertierung der C ++ - Klasse in JSON

  • Ich möchte eine JSON-Zeichenfolge erstellen, die die Instanzvariablen meiner Klasse enthält.

    Zum Beispiel

     class Example {  
        std::string string;  
        std::map<std::string, std:string> map;  
        std::vector<int> vector;  
    };
     

    würde zu:

     {
        "string":"the-string-value",
        "map": {
            "key1":"val1",
            "key2":"val2"
        },
        "vector":[1,2,3,4]
    }
     

    Ich habe mir mehrere C ++ - Bibliotheken zur Erstellung von JSON angesehen, die alle unglaublich komplex erscheinen. Ich möchte etwas Ähnliches wie Javascript JSON.stringify(object). Mit anderen Worten: Übergeben Sie einfach eine std :: map und erhalten Sie eine Zeichenfolge. Die Karte kann andere Karten, Vektoren, Listen, Strings, Zahlen und Booles enthalten.

    Wie können Sie dies am besten tun?

    Bearbeiten

    Ich habe Folgendes untersucht:

    Json Spirit, Jsoncpp, Zoolib, JOST, CAJUN, Libjson, Nosjob, JsonBox, Jsonme -

    Was ich verstehen kann, kann ich konstruieren ein separates JSON-Objekt wie in einer Antwort unten und in JSON konvertieren Ich möchte meine Sachen in Standardsammlungen speichern und konvertieren können.

    Bearbeiten 2

    Die Idee der Serialisierung einer Klasse sollte ausrangiert werden, da es anscheinend unmöglich ist, da C ++ keine Reflektion aufweist.

    Gibt es Eine nette Möglichkeit, eine std :: map, die std: maps, std :: Vectors, std :: liste, Zahlen, Strings und Bools enthält, in JSON zu konvertieren, ohne Datentypen ändern oder Daten in einen neuen Datentyp kopieren zu müssen?

    Danke.

    22 November 2011
    tgt
7 answers
  • JSON Spirit würde es Ihnen folgendermaßen ermöglichen:

     Object addr_obj;
    
    addr_obj.push_back( Pair( "house_number", 42 ) );
    addr_obj.push_back( Pair( "road",         "East Street" ) );
    addr_obj.push_back( Pair( "town",         "Newtown" ) );
    
    ofstream os( "address.txt" );
    write( addr_obj, os, pretty_print );
    os.close();
     

    Ausgabe:

     {
        "house_number" : 42,
        "road" : "East Street",
        "town" : "Newtown"
    }
     

    Die json_map_demo.cpp wäre ein guter Anfang, ich Angenommen.

    22 November 2011
    sehecw.prime
  • Jede gute C ++ - JSON-Bibliothek sollte dies tun, und es ist traurig, dass dies nicht der Fall ist - mit Ausnahme von ThorsSerializer und anscheinend Nosjob , wie in dieser Frage erwähnt .

    Natürlich gibt es in C ++ keine Spiegelung wie bei Java, daher müssen Sie Ihre Typen explizit kommentieren:
    (kopiert aus der ThorsSerializer-Dokumentation)

     #include "ThorSerialize/JsonThor.h"
    #include "ThorSerialize/SerUtil.h"
    #include <map>
    #include <vector>
    #include <string>
    #include <iostream>
    
    class Example {
        std::string string;
        std::map<std::string, std::string> map;
        std::vector<int> vector;
    
        // Allow access to the class by the serialization library.
        friend class ThorsAnvil::Serialize::Traits<Example>;
    
        public:
            Example(std::string const& s, std::map<std::string, std::string> const& m, std::vector<int> const& v)
                : string(s), map(m), vector(v)
            {}
    };
    
    // Define what members need to be serilizable
    ThorsAnvil_MakeTrait(Example, string, map, vector);
     

    Verwendungsbeispiel:

     int main()
    {
        using ThorsAnvil::Serialize::jsonExport;
        using ThorsAnvil::Serialize::jsonImport;
    
    
        Example     e1 {"Some Text", {{"ace", "the best"}, {"king", "second best"}}, {1 ,2 ,3, 4}};
    
        // Simply serialize object to json using a stream.
        std::cout << jsonExport(e1) << "\n";
    
        // Deserialize json text from a stream into object.
        std::cin  >> jsonImport(e1);
    }
     

    Laufen:

     {
        "string": "Some Text",
        "map":
        {
            "ace": "the best",
            "king": "second best"
        },
        "vector": [ 1, 2, 3, 4]
    }
     

    In C ++ können Sie nichts Besseres tun.

    11 July 2018
    Martin YorkBen Voigt
  • Ich habe eine Bibliothek geschrieben, die Ihr Problem lösen soll. Es ist jedoch ein sehr neues Projekt, das nicht stabil genug ist. Fühlen Sie sich frei, einen Blick darauf zu werfen, die Startseite ist hier ::

    https://github.com/Mizuchi/acml

    In Ihrem Beispiel müssen Sie eine Zeile wie folgt hinzufügen:

     ACML_REGISTER(Example, ,(string)(map)(vector));
     

    Um der Bibliothek mitzuteilen, welches Mitglied Sie sichern möchten. Da C ++ keine Spiegelung hat. Und Sie müssen einen Zugriff auf das Mitglied gewähren. Verwenden Sie entweder öffentliche Mitgliedsebene oder Verwenden Sie die Friend-Klasse.

    Und später müssen Sie nur noch Folgendes tun:

    string result = acml :: json :: dumps (any_object);

    würde zu:

     {
        "string": "the-string-value",
        "map":
        {
            "key1": "val1",
            "key2": "val2"
        },
        "vector":
        {
            "type": "std::vector",
            "size": "4",
            "0": "1",
            "1": "2",
            "2": "3",
            "3": "4"
        }
    }
     

    Wie Sie sehen, ist das JSON-Array noch nicht implementiert. Jetzt wird alles zu einem String.

    20 April 2013
    ytj
  • Möchten Sie eine Karte oder ein Objekt in JSON-Format speichern? (Ihr Beispiel zeigt eine Klasse, Sie sagen jedoch eine Karte). Eine Karte finden Sie in dieser Bibliothek - JSON Spirit .

    Für Objekte: In C ++ gibt es keine Reflektionsunterstützung (abgesehen von der sehr begrenzten RTTI). Daher gibt es auch keine "One-Click" -Lösung für die Serialisierung. Bei jeder Lösung müssen Sie zusätzlichen, möglicherweise eng gekoppelten Code für die Klasse schreiben, die Sie serialisieren und deserialisieren möchten (dies hängt davon ab, ob Sie nicht öffentliche Daten serialisieren möchten).

    10 August 2018
    Vadim Kotovchester89
  • Ich habe eine experimentelle Bibliothek geschrieben, die die Aufgabe erfüllen kann, aber es erfordert eine externe Beschreibung der Klassenstrukturen und -hierarchie. Es verwendet GCCXML, um ein XML-Wörterbuch zu erstellen, das für die Deserialisierung von Serialisierung verwendet wird:

    http://code.google.com/p/cjson/

    Es ist im Moment ein experimentelles Projekt, das grundlegende Typen behandeln kann (int, float double), Zeiger auf grundlegende Typen, Klassen, geerbte Member usw. Es werden grundlegende Standardisierungen von std :: vector und std :: map sowie von std :: string-Instanzen implementiert.

    Weitere Informationen zur Implementierung hier

    15 December 2013
    JBV06
  • Wenn die Frage noch aktuell ist, schauen Sie sich die Bibliothek json_dto an kleiner Header-Only-Helper zum Konvertieren von Daten zwischen JSON-Repräsentation und C ++ - Strukturen.

    Für Beispiel mit den folgenden Strukturen:

     struct message_source_t
    {
      // Worker thread.
      std::int32_t m_thread_id;
    
      // Sender.
      std::string m_subsystem;
    };
    
    struct message_t
    {
      // Who sent a message.
      message_source_t m_from;
    
      // When the message was sent (unixtime).
      std::tm m_when;
    
      // Message text.
      std::string m_text;
    };
     

    Mit Hilfe von json_dto können Sie die folgende JSON erstellen:

     {
      "from" : 
        {
          "thread_id" : 4242,
          "sybsystem" : "json_dto"
        },
      "when" : "2016.09.28 19:55:00",
      "text" : "Hello world!"
    }  
     

    Wenn Sie eine solche JSON-Zeichenfolge haben, können Sie sie in Strukturen konvertieren.

    10 August 2018
    Vadim Kotovchester89
  • dieses Python-Skript generiert C ++ - Pod-Klassen mit einem Member für jede json-Eigenschaft

    Sie wollen das Gegenteil, aber es ist trivial, eine Mapping-Klasse zu erstellen, die sowohl den geladenen als auch den gespeicherten

    -Logo verwendet eine externe Json-Parser-Bibliothek

    04 November 2015
    kcris