C++ Json Library 사용하기 위해 조사한 결과 크게 2가지가 있다.
- JsonCPP : http://jsoncpp.sourceforge.net/roadmap.html
- Rapid Json : http://rapidjson.org
JsonCPP 와 RapidJson 라이브러리는 C++ 로 되어있는 라이브러리 중 가장 인기 있는 2가지 인것으로 보인다.
아래는 다른 사람들이 조사한 다른 라이브러리들 비교 정리해놓은 링크이다.
- http://jason-heo.github.io/programming/2012/03/06/jsoncpp1.html
- https://blog.thousandeyes.com/efficiency-comparison-c-json-libraries/
Json Library 선택 하기 위한 요소로는
- 커뮤니티 및 예제 코드 수, 사용자 수
- Parsing 속도
- .cpp .h 파일로 사용가능
- Json Member 의 순서 입력 가능 여부
링크 : https://cpp.libhunt.com/compare-rapidjson-vs-jsoncpp
위 링크에서 보았을 때 선택 요소 1번에서는 RapidJson 의 승리였다.
github 의 Starts 및 Watchers 수가 RapidJson 의 승리다.
2. Parsing 속도
Parsing 속도에서도 Rapidjson 은 13 ms , JsonCPP 는 171 ms 로
RapidJson 의 속도가 10배 이상 빠르다고 나와있다.
JsonCPP
1) 설치 방법
1. jsoncpp 공식 github 에서 라이브러리 다운로드 |
]# git clone https://github.com/open-source-parsers/jsoncpp.git |
2. 다운로드 후 설치 시, dist 디렉터리에 라이브러리 파일들 생김 |
]# python ./amalgamate.py ]# tree dist/
|
위 2단계면 우선 라이브러리 사용에 대한 준비는 끝이다.
컴파일 시 위 3개의 파일만 추가해주면 사용이 가능하다.
2) 사용 예시 (Read Json)
#include "json/json.h" #include#define JSON_FILE "sample.json" bool ReadFromFile(const char* filename, char* buffer, int len) { FILE* r = fopen(filename, "rb"); if (NULL == r) return false; size_t fileSize = fread(buffer, 1, len, r); fclose(r); return true; } int main(int argc, char* argv[]) { const int BufferLength = 102400; char readBuffer[BufferLength] = {0,}; if (false == ReadFromFile(JSON_FILE, readBuffer, BufferLength)) return 0; std::string config_doc = readBuffer; Json::Value rootr; Json::Reader reader; bool parsingSuccessful = reader.parse( config_doc, rootr ); if ( !parsingSuccessful ) { std::cout << "Failed to parse configuration\n" << reader.getFormatedErrorMessages(); return 0; } std::cout << rootr["Dhcp4"]["control-socket"]["socket-type"].asString() << std::endl; return 0; }
위 코드는 json 파일의 내용을 읽어 특정 Member 를 출력하는 코드이다.
JsonCPP 는 멤버 접근이 위처럼 대괄호로 멤버 접근이 가능하여 코드 가독성이 좋고 간결하다.
Rapid Json
1) 설치 방법
1. git hub 에서 다운로드 |
]# git clone https://github.com/Tencent/rapidjson/ |
2. 라이브러리 설치 |
]# cd rapidjson ]# git submodule update --init ]# mkdir build ]# cd build ]# cmake;make; |
2) 사용 예시
#include "rapidjson/document.h" // rapidjson's DOM-style API #include "rapidjson/prettywriter.h" // for stringify JSON #includeusing namespace rapidjson; using namespace std; int main(int, char*[]) { const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } "; Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator. // In-situ parsing, decode strings directly in the source string. Source must be string. char buffer[sizeof(json)]; memcpy(buffer, json, sizeof(json)); if (document.ParseInsitu(buffer).HasParseError()) return 1; printf("\nParsing to document succeeded.\n"); printf("\nAccess values in document:\n"); assert(document.IsObject()); // Document is a JSON value represents the root of DOM. Root can be either an object or array. assert(document.HasMember("hello")); assert(document["hello"].IsString()); printf("hello = %s\n", document["hello"].GetString()); // Since version 0.2, you can use single lookup to check the existing of member and its value: Value::MemberIterator hello = document.FindMember("hello"); assert(hello != document.MemberEnd()); assert(hello->value.IsString()); assert(strcmp("world", hello->value.GetString()) == 0); (void)hello; assert(document["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue(). printf("t = %s\n", document["t"].GetBool() ? "true" : "false"); assert(document["f"].IsBool()); printf("f = %s\n", document["f"].GetBool() ? "true" : "false"); printf("n = %s\n", document["n"].IsNull() ? "null" : "?"); assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type. assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true. printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"] assert(document["pi"].IsNumber()); assert(document["pi"].IsDouble()); printf("pi = %g\n", document["pi"].GetDouble()); { const Value& a = document["a"]; // Using a reference for consecutive access is handy and faster. assert(a.IsArray()); for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t. printf("a[%d] = %d\n", i, a[i].GetInt()); int y = a[0].GetInt(); (void)y; // Iterating array with iterators printf("a = "); for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) printf("%d ", itr->GetInt()); printf("\n"); } }
위 코드는 rapidjson 에서 제공하는 tutorial 의 Json Read 파트 일부를 발췌한 것이다.
샘플코드에서 알 수 있듯이 rapidjson 라이브러리는 assert 를 굉장히 좋아한다.
'개발 노트 > C , C++' 카테고리의 다른 글
[Socket] Get socket information by socket descriptor : getsockname() (0) | 2019.06.11 |
---|---|
MFC와 CppSQLite3U 연동방법 (0) | 2018.10.04 |