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), 지도에는 다른 지도, 벡터, 목록, 문자열, 숫자 및 부울이 포함될 수 있습니다.
어떻게 하면 가장 좋은 방법일까요?
도와주셔서 고마워요.
편집
다음을 조사했습니다.
json spirit, jsoncpp, zoolib, JOST, CAJUN, libjson, nosjob, jsonBox, jsonme--
아래 답변과 같이 별도의 JSON 오브젝트를 작성하여 JSON으로 변환할 수 있는 것으로 알고 있습니다.표준 컬렉션에 저장하여 변환하고 싶습니다.
편집 2
좋아요, C++의 반성이 부족하기 때문에 불가능한 것 같기 때문에 수업을 연재하는 생각은 그만두세요.
std:maps, std::vectors, std:lists, 숫자, 문자열 및 bools를 포함하는 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을 제외하고 그렇지 않은 것은 유감입니다.
에는 Java와 「C++」 타입에 으로 주석을 합니다.
(Thors Serializer 뉴뉴 ( ( )
#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++는 반사가 없기 때문에그리고 회원에게 공개 회원 레벨을 사용하거나 친구 클래스를 사용하는 방법을 제공해야 합니다.
그리고 나중에는 이렇게 하면 됩니다.
문자열 결과 = acml::json::syslog(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을 참조하십시오.
객체의 경우:(매우 제한된 RTI를 제외하고) C++에서는 리플렉션이 지원되지 않으므로 시리얼화를 위한 "원클릭" 솔루션도 없습니다.어떤 솔루션에서도 시리얼화 및 시리얼화 해제(비공개 데이터의 시리얼화 여부에 따라 다름)하는 클래스에 긴밀하게 결합된 추가 코드를 작성해야 합니다.
시리얼(http://uscilab.github.io/cereal/))을 본 적이 있습니까?C++ 를 사용해 JSON 와의 시리얼화를 실시하기 위한 JSON 아카이브가 있습니다.
(시리얼의) 오버헤드가 최소인 예는 SO에서 찾을 수 있습니다.https://stackoverflow.com/a/22587527/255635
저는 https://github.com/beached/daw_json_link의 저자입니다.C++는 지금 반사가 없기 때문에, 심플한 것을 없애면 좋을 것 같습니다.그러나 단순한 선언적 매핑을 정의함으로써 JSON Link는 유형에 대해 유형 체크 파서를 제공합니다.예를 들어 지정한 클래스는 다음과 같이 매핑할 수 있습니다.
class Example {
std::string string;
std::map<std::string, std:string> map;
std::vector<int> vector;
};
namespace daw::json {
template<>
struct json_data_contract<Example> {
using type = json_member_list<
json_link<"string", std::string>,
json_link<"map", std::map<std::string, std::string>>
json_link<"vector", std::vector<int>>>;
static inline auto to_json_data( Example const & v ) {
return std::forward_as_tuple( v.string, v.map, v.vector );
}
};
}
매핑은 서부터 다른 안에 매핑을 '어리다'로 할 수 .json_class<"Name", Example>하는 건 '연재하다'의 일 뿐이에요auto json_document = daw::json::to_json( MyExampleValue ) 해석하기 .daw::json::from_json<Example>( json_document );라이브러리의 장점은 사용자 유형에 맞는 커스텀 파서를 생성하고 데이터를 구문 분석할 때 유형 검사를 수행하는 것입니다.
이는 사용자 정의 사전에서 수동으로 키와 값을 만들거나 유지 관리할 필요 없이 기존 클래스/구조의 멤버 변수를 선택적으로 저장할 수 있는 매우 가벼운 솔루션입니다.nlohmann json(부스트 또는 기타 무거운 라이브러리 없음)만 사용합니다.
nlohmann::json을 사용하면 임의의 유형의 변환을 할 수 있습니다.상세한 것에 대하여는, https://nlohmann.github.io/json/features/arbitrary_types/ 를 참조해 주세요.
코드:
// example.cc
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include "third_party/nlohmann/json.hpp"
struct Example {
std::string name;
std::map<std::string, int> dict;
std::vector<int> vec;
std::string this_member_is_not_part_of_the_json;
};
// Use NLOHMANN_DEFINE_TYPE_INTRUSIVE if your members are private.
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example,
name,
dict,
vec);
int main() {
Example example;
example.name = "Example";
example.dict = {{"AnyKey", 42}};
example.vec = {1, 2, 3};
nlohmann::json json;
to_json(json, example); // "generated" function
std::cout << json.dump(1) << std::endl;
return 0;
}
코드를 컴파일합니다.
g++ -I third_party/nlohmann/ example.cc -o example
../example★★★★
{
"dict": {
"AnyKey": 42
},
"name": "Example",
"vec": [
1,
2,
3
]
}
설명:
: ★★★★★★★★★★★★★★★★★★★★★★★★★★★」NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE 정의 에서, 은 함수 "이러면 안 돼요"를 합니다.to_json(...)같은 네임스페이스에 있습니다.
json.dump(1)조손
저는 이 작업을 수행할 수 있는 실험 라이브러리를 작성했습니다만, 클래스 구조와 계층에 대한 외부 설명이 필요합니다.GCCXML을 사용하여 시리얼화 디시리얼라이제이션에 사용되는 xml 사전을 구축합니다.
http://code.google.com/p/cjson/
지금은 기본형(int, float double), 기본형, 클래스, 상속된 멤버 등에 대한 포인터 등을 다룰 수 있는 실험 프로젝트입니다.기본 std::vector ans std::map serialization을 구현하고 std::string 인스턴스도 구현합니다.
구현에 대한 자세한 내용은 여기를 참조하십시오.
#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"
]
}
RareCpp에서는 리플렉션 구현 위에 매우 효과적인 JSON 라이브러리를 만들었습니다.C++17용으로 작성되었으며 Visual Studios, g++, Clang과 함께 사용할 수 있습니다.라이브러리는 헤더 전용입니다.즉, 이 라이브러리를 사용하려면 reflect 헤더와 json 헤더만 프로젝트에 복사하면 됩니다.
JSON 라이브러리는 REFLET 매크로에서 필드를 한 번만 나열하면 됩니다.이러한 매크로에서는 읽기 또는 쓰기에 적합한 JSON 출력 표현을 자동으로 식별하고 반사된 필드뿐만 아니라 어레이, STL 컨테이너, 참조, 포인터 등을 재귀적으로 통과할 수 있습니다.
struct MyOtherObject { int myOtherInt; REFLECT(MyOtherObject, myOtherInt) };
struct MyObject
{
int myInt;
std::string myString;
MyOtherObject myOtherObject;
std::vector<int> myIntCollection;
REFLECT(MyObject, myInt, myString, myOtherObject, myIntCollection)
};
int main()
{
MyObject myObject = {};
std::cout << "Enter MyObject:" << std::endl;
std::cin >> Json::in(myObject);
std::cout << std::endl << std::endl << "You entered:" << std::endl;
std::cout << Json::pretty(myObject);
}
상기의 내용은 다음과 같이 실행할 수 있습니다.
Enter MyObject:
{
"myInt": 1337, "myString": "stringy", "myIntCollection": [2,4,6],
"myOtherObject": {
"myOtherInt": 9001
}
}
You entered:
{
"myInt": 1337,
"myString": "stringy",
"myOtherObject": {
"myOtherInt": 9001
},
"myIntCollection": [ 2, 4, 6 ]
}
필드에 주석을 달아 JSON 표현에서 다른 이름을 지정하거나 문자열로 강제 지정하는 등의 작업을 수행할 수도 있습니다.
struct Point
{
NOTE(latitude, Json::Name{"lat"})
double latitude;
NOTE(longitude, Json::Name{"long"})
double longitude;
REFLECT(Point, latitude, longitude)
};
자세한 예는 여기를 참조해 주세요.슈퍼 클래스 캡처, 컴파일 시 알려지지 않은 JSON 읽기, 트래버스 및 쓰기 지원, 특정 필드 또는 유형에 대한 JSON 표현 추가 커스터마이즈 등 다양한 기능이 있습니다.
이 python 스크립트는 각 json 속성에 대해 하나의 멤버로 c++ 포드 클래스를 생성합니다.
당신은 정반대의 것을 원하지만 로드와 저장을 모두 하는 매핑 클래스를 생성하는 것은 간단하다.
생성된 코드는 외부 json 파서 라이브러리에 의존합니다.
질문이 여전히 실제인 경우 JSON 표현과 c++ 구조체 간의 데이터 변환을 위한 작은 헤더 전용 도우미인 json_dto 라이브러리를 살펴봅니다.
예를 들어 다음과 같은 구조를 갖습니다.
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;
};
json_dto를 사용하여 다음 JSON을 생성할 수 있습니다.
{
"from" :
{
"thread_id" : 4242,
"sybsystem" : "json_dto"
},
"when" : "2016.09.28 19:55:00",
"text" : "Hello world!"
}
이러한 JSON 문자열을 지정하면 구조체로 변환할 수 있습니다.
언급URL : https://stackoverflow.com/questions/8220130/converting-c-class-to-json
'programing' 카테고리의 다른 글
| 파일에서 ESLint react/prop-type 규칙을 비활성화하려면 어떻게 해야 합니까? (0) | 2023.03.28 |
|---|---|
| AngularJS: 렌더링 후 콜백(렌더 후 DOM으로 작업) (0) | 2023.03.28 |
| Amazon EC2 - PHP GD 이미지 라이브러리 (0) | 2023.03.28 |
| 워드프레스의 하위 도메인이 계속 주 도메인으로 리디렉션됨 (0) | 2023.03.28 |
| 값에 따른 json의 python 정렬 목록 (0) | 2023.03.28 |