boost json라이브러리를 사용하면 구조체와 json문자열 간의 상호 변환이 간단합니다. 여기서는 간단한 변환 예를 살펴보며 사용법을 알아보겠습니다.
우선 아래와 같은 간단한 예로 살펴보겠습니다.
#include <iostream>
#include <string>
#include <boost/json.hpp>
using namespace std;
struct user
{
int id;
string name;
bool login;
};
void tag_invoke(boost::json::value_from_tag, boost::json::value& jv, user const& u)
{
jv =
{
{"id", u.id},
{"name", u.name},
{"login", u.login}
};
}
user tag_invoke(boost::json::value_to_tag<user>, boost::json::value const& jv)
{
boost::json::object const& obj = jv.as_object();
return user
{
boost::json::value_to<int>(obj.at("id")),
boost::json::value_to<string>(obj.at("name")),
boost::json::value_to<bool>(obj.at("login"))
};
}
void to_user(boost::json::value const& jv, user& out)
{
boost::json::object const& obj = jv.as_object();
out.id = boost::json::value_to<int>(obj.at("id"));
out.name = boost::json::value_to<string>(obj.at("name"));
out.login = boost::json::value_to<bool>(obj.at("login"));
}
int main(int argc, char* argv[])
{
user object{ 777, "DevMemo", true };
//부분 #1: 구조체 -> json 문자열
boost::json::value jv = boost::json::value_from(object);
string json = boost::json::serialize(jv);
cout << json << endl;
//부분 #2: json 문자열 -> 구조체
boost::json::error_code ec;
boost::json::value jv2 = boost::json::parse(json, ec);
if (ec.failed())
{
cout << ec.message() << endl;
return -1;
}
user from_json(boost::json::value_to<user>(jv2));
cout << "user: " << from_json.id << ", " << from_json.name << ", " << from_json.login << endl;
//부분 #3: json 문자열 -> 구조체 방법2
user from_json2;
to_user(jv2, from_json2);
cout << "user: " << from_json2.id << ", " << from_json2.name << ", " << from_json2.login << endl;
return 0;
}
해당 소스에 대한 결과는 아래와 같습니다.
{"id":777,"name":"DevMemo","login":true}
user: 777, DevMemo, 1
user: 777, DevMemo, 1
위의 주석 부분을 참고하시며 아래 부분을 설명을 살펴 보겠습니다.
//부분 #1: 구조체 -> json 문자열
boost::json::value_from(object)을 수행하기 위하여 tag_invoke(boost::json::value_from_tag... 부분 함수를 예제처럼 정의하여 주어야 합니다. 여기서 tag_invoke 함수는 구조체를 json::value로 변환하는 역활을 합니다.
json::value 값은 boost::json::serialize 함수를 통하여 json문자열이 됩니다. 주의할점은 이 함수는 문자열을 UTF-8로 별도로 변환하지 않는 관계로 JSON 관련해서 UTF-8을 필요로 할 경우 결과 값을 가지고 별도의 변환을 해주어야 합니다.
참고: boost locale을 이용한 C++에서의 Multi Byte와 UTF8간의 문자열 변환
//부분 #2: json 문자열 -> 구조체
user from_json(boost::json::value_to<user>(jv2)) 을 수행하기 위하여 tag_invoke(boost::json::value_to_tag...부분 함수를 예제처럼 정의하여 주어야 합니다. 여기서 tag_invoke 함수는 json::value 값을 구조체로 변환하는 역활을 합니다.
boost::json::parse 함수를 통하여 json:value로 변환할 때 파싱하는 json 문자열은 UTF-8로 인코딩되어 있어야 합니다. 영문이나 숫자는 상관없지만 한글과 같은 경우 파싱에러가 납니다. 이 에러는 error_code구조체 인자를 통하여 알 수 있습니다.
//부분 #3: json 문자열 -> 구조체 방법2
부분 #2에 있는 방법이 boost json라이브러리의 정식 방법인데 소스에서 보이는 것처럼 불필요한 암묵적 복사가 일어나는 것을 알 수 있습니다. JSON이 간단한 경우야 상관 없겠지만 복잡해서 구조체의 용량이 클경우 복사가 있는 정식 방법을 사용하는 것은 일정량의 오버헤드를 야기할 수도 있습니다. 이럴 경우 이 부분의 예제처럼 json::value와 구조체의 변환을 to_user함수와 같이 정의하고 사용하는 것도 좋을 거 같습니다.
'개발 라이브러리 & 툴' 카테고리의 다른 글
C++ boost json array 생성 및 파싱 예제 (0) | 2022.05.06 |
---|---|
MS 비동기 에이전트 라이브러리 소개: #2 Hello World (0) | 2021.12.25 |
MS 비동기 에이전트 라이브러리 소개: #1 개념 (0) | 2021.12.24 |
비주얼스튜디오(Visual Studio) 솔루션(*.sln) 커맨드라인 빌드 응용 (0) | 2021.11.30 |
[MongoDB] C/C++ BSON 한글 문자열 입출력 (0) | 2021.11.20 |
boost locale을 이용한 C++에서의 Multi Byte와 UTF8간의 문자열 변환 (0) | 2021.11.19 |
[MongoDB] Mongo C/C++ Driver 관련 자료 (0) | 2021.11.10 |
boost asio address from_string 사용시 주의할 점 (0) | 2021.10.25 |