programing

C ++ 클래스를 JSON으로 변환

projobs 2021. 1. 16. 09:11
반응형

C ++ 클래스를 JSON으로 변환


내 클래스의 인스턴스 변수를 포함하는 JSON 문자열을 만들고 싶습니다.

예를 들면

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

될 것입니다 :

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

JSON을 만들기 위해 여러 C ++ 라이브러리를 살펴 봤는데 모두 엄청나게 복잡해 보입니다. Javascript의 JSON.stringify(object). 즉, std :: map을 전달하고 문자열을받습니다. 지도에는 다른지도, 벡터, 목록, 문자열, 숫자 및 부울이 포함될 수 있습니다.

이를 수행하는 가장 좋은 방법은 무엇입니까?

당신의 도움을 주셔서 감사합니다.

편집하다

다음을 살펴 보았습니다.

json spirit, jsoncpp, zoolib, JOST, CAJUN, libjson, nosjob, JsonBox, jsonme--

아래 답변과 같이 별도의 JSON 개체를 구성하고 JSON으로 변환 할 수 있음을 이해합니다. 내 물건을 표준 컬렉션에 저장하고 변환 할 수 있기를 바랍니다.

편집 2

좋아, C ++의 반사 부족으로 불가능 해 보이기 때문에 클래스 직렬화 아이디어를 폐기하십시오.

데이터 유형을 변경하거나 데이터를 새 데이터 유형으로 복사하지 않고 std : maps, std :: vectors, std :: lists, 숫자, 문자열 및 bool을 포함하는 std :: map을 JSON으로 변환하는 좋은 방법이 있습니까?

감사.


JSON Spirit 을 사용하면 다음과 같이 할 수 있습니다.

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" );
os.write( addr_obj, os, pretty_print );
os.close();

산출:

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

json_map_demo.cpp가 시작하기에 좋은 장소가 될 것입니다, 나는 가정한다.


좋은 C ++ JSON 라이브러리는이 작업을 수행해야하며 그렇지 않다는 사실을 아는 것은 슬픈 일 입니다. 질문 에서 언급 한 ThorsSerializer 와 분명히 Nosjob제외하고는 말입니다 .

물론 C ++에는 Java와 같은 리플렉션이 없으므로 유형에 명시 적으로 주석을 추가해야합니다
(ThorsSerializer 문서에서 복사).

#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);

사용 예 :

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);
}

달리는:

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

C ++에서는 이것보다 더 잘할 수 없습니다.


나는 당신의 문제를 해결하기 위해 설계된 라이브러리를 썼습니다. 그러나 이것은 매우 새로운 프로젝트이며 충분히 안정적이지 않습니다. 자유롭게 살펴보십시오. 홈페이지는 다음과 같습니다.

https://github.com/Mizuchi/acml

귀하의 예에서 다음과 같이 한 줄을 추가해야합니다.

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

덤프 할 멤버를 라이브러리에 알리기 위해. C ++에는 반사가 없습니다. 그리고 공개 멤버 레벨을 사용하거나 친구 클래스를 사용하여 멤버에 액세스하는 방법을 제공해야합니다.

그리고 나중에 다음과 같이 sth를 수행하면됩니다.

문자열 결과 = acml :: json :: dumps (any_object);

될 것입니다 ::

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

보시다시피 JSON 배열은 아직 구현되지 않았습니다. 이제 모든 것이 끈이됩니다.


지도 또는 객체를 JSON 화 하시겠습니까? (당신의 예는 수업을 보여 주지만 당신은지도를 말합니다). 지도는이 라이브러리 -JSON Spirit을 확인하십시오 .

객체의 경우 : C ++에는 리플렉션이 지원되지 않으므로 (매우 제한된 RTTI는 제외) 직렬화를위한 "원 클릭"솔루션도 없습니다. 모든 솔루션을 사용하려면 직렬화 및 역 직렬화하려는 클래스에 추가로 밀접하게 결합 된 코드를 작성해야합니다 (비공개 데이터를 직렬화하려는 경우에 따라 다름).


시리얼 ( http://uscilab.github.io/cereal/ )을 보셨습니까 ? C ++를 사용하여 JSON과 직렬화하기위한 JSON 아카이브가 있습니다.

(시리얼에서) 최소한의 오버 헤드가있는 예는 여기에서 찾을 수 있습니다 : https://stackoverflow.com/a/22587527/255635


작업을 수행 할 수있는 실험적 라이브러리를 작성했지만 클래스 구조 및 계층에 대한 외부 설명이 필요합니다. 직렬화 역 직렬화에 사용되는 xml 사전을 빌드하기 위해 GCCXML을 사용합니다.

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

기본 유형 (int, float double), 기본 유형에 대한 포인터, 클래스, 상속 된 멤버 등을 처리 할 수있는 실험 프로젝트입니다. 기본 std :: vector 및 std :: map 직렬화를 구현합니다. std :: string 인스턴스.

여기 에서 구현에 대한 세부 정보를 참조 하십시오.


Boost.PropertyTree를 사용할 수 있습니다 .

#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

namespace pt = boost::property_tree;

int main() {
    // Create an empty property tree object.
    pt::ptree tree;

    // Put a string value into the tree.
    tree.put("string", "the-string-value");

    // Put a map object into the tree.
    pt::ptree child1;
    std::map<std::string, std::string> map = {{"key1", "val1"},
                                              {"key2", "val2"}};
    for (auto &p : map) {
        child1.add(p.first, p.second);
    }
    tree.add_child("map", child1);

    // Put a vector of numbers into the tree
    pt::ptree child2;
    std::vector<int> vector = {1, 2, 3, 4};
    for (auto &v : vector) {
        pt::ptree item;
        item.put("", v);
        child2.push_back(std::make_pair("", item));
    }
    tree.add_child("vector", child2);

    // Write property tree to JSON file
    pt::write_json("output.json", tree);

    return 0;
}

산출:

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

파이썬 스크립트는 각 json 속성에 대해 하나의 멤버로 C ++ 포드 클래스를 생성합니다.

you want quite the opposite thing, but is trivial to generate a mapping class which does both loading and saving

generated code relies on an external json parser library


If the question is still actual, then look at json_dto library, a small header-only helper for converting data between JSON representation and c++ structs.

For example having the following structs:

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;
};

with the help of json_dto you can create the following JSON:

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

And given such JSON string you can convert it to structs.

ReferenceURL : https://stackoverflow.com/questions/8220130/converting-c-class-to-json

반응형