JSON → C++ 변환기

JSON 샘플에서 nlohmann/json 직렬화 함수를 갖춘 C++ 클래스를 생성합니다.

JSON에서 nlohmann/json용 C++ 클래스 생성

C++에는 기본 JSON 지원이 없으며, 널리 쓰이는 nlohmann/json 라이브러리로 타입을 자동 변환하려면 타입마다 from_json과 to_json 함수가 필요합니다. 이 변환기는 객체마다 private 멤버, getter, setter를 갖춘 클래스와 그에 맞는 from_json/to_json 함수를 선언한 헤더를 작성해 주므로, json.get<SensorReading>()이나 객체를 다시 json에 대입하는 코드가 그대로 동작합니다. 정수는 int64_t, 소수는 double, 문자열은 std::string이 됩니다.

사용 방법

  1. 디바이스 메시지나 설정 파일 같은 JSON 샘플을 붙여넣습니다.
  2. 루트 클래스 이름을 입력합니다. 예: SensorReading.
  3. 출력을 헤더 파일로 저장하고 nlohmann/json의 json.hpp를 include 경로에 추가한 뒤, nlohmann::json::parse(text).get<quicktype::SensorReading>()으로 파싱합니다.

자주 묻는 질문

생성된 코드에 어떤 라이브러리가 필요한가요?
단일 헤더 라이브러리인 nlohmann/json(json.hpp)이 필요합니다. 헤더는 선택적 필드에 사용되는 boost/optional.hpp도 include하는데, JSON에 선택적 필드가 없다면 이 include는 제거해도 됩니다.
어떤 C++ 표준이 필요한가요?
nlohmann/json은 C++11 이상이 필요합니다. 위의 라이브러리를 제외하면 생성된 헤더는 표준 라이브러리 타입만 사용합니다.
quicktype 네임스페이스를 바꿀 수 있나요?
네. namespace quicktype을 원하는 이름으로 바꾸세요. from_json과 to_json이 클래스와 같은 네임스페이스에 있는 한 인자 의존 탐색(ADL)으로 찾아집니다.

예시: JSON to C++

입력 JSON

{
  "sensor_id": "temp-01",
  "value": 21.5,
  "unit": "C",
  "battery": 87,
  "ok": true
}

생성된 C++ 코드 (SensorReading)

//  To parse this JSON data, first install
//
//      Boost     http://www.boost.org
//      json.hpp  https://github.com/nlohmann/json
//
//  Then include this file, and then do
//
//     SensorReading data = nlohmann::json::parse(jsonString);

#pragma once

#include "json.hpp"

#include <boost/optional.hpp>
#include <stdexcept>
#include <regex>

namespace quicktype {
    using nlohmann::json;

    #ifndef NLOHMANN_UNTYPED_quicktype_HELPER
    #define NLOHMANN_UNTYPED_quicktype_HELPER
    inline json get_untyped(const json & j, const char * property) {
        if (j.find(property) != j.end()) {
            return j.at(property).get<json>();
        }
        return json();
    }

    inline json get_untyped(const json & j, std::string property) {
        return get_untyped(j, property.data());
    }
    #endif

    class SensorReading {
        public:
        SensorReading() = default;
        virtual ~SensorReading() = default;

        private:
        std::string sensor_id;
        double value;
        std::string unit;
        int64_t battery;
        bool ok;

        public:
        const std::string & get_sensor_id() const { return sensor_id; }
        std::string & get_mutable_sensor_id() { return sensor_id; }
        void set_sensor_id(const std::string & value) { this->sensor_id = value; }

        const double & get_value() const { return value; }
        double & get_mutable_value() { return value; }
        void set_value(const double & value) { this->value = value; }

        const std::string & get_unit() const { return unit; }
        std::string & get_mutable_unit() { return unit; }
        void set_unit(const std::string & value) { this->unit = value; }

        const int64_t & get_battery() const { return battery; }
        int64_t & get_mutable_battery() { return battery; }
        void set_battery(const int64_t & value) { this->battery = value; }

        const bool & get_ok() const { return ok; }
        bool & get_mutable_ok() { return ok; }
        void set_ok(const bool & value) { this->ok = value; }
    };
}

namespace quicktype {
    void from_json(const json & j, SensorReading & x);
    void to_json(json & j, const SensorReading & x);

    inline void from_json(const json & j, SensorReading& x) {
        x.set_sensor_id(j.at("sensor_id").get<std::string>());
        x.set_value(j.at("value").get<double>());
        x.set_unit(j.at("unit").get<std::string>());
        x.set_battery(j.at("battery").get<int64_t>());
        x.set_ok(j.at("ok").get<bool>());
    }

    inline void to_json(json & j, const SensorReading & x) {
        j = json::object();
        j["sensor_id"] = x.get_sensor_id();
        j["value"] = x.get_value();
        j["unit"] = x.get_unit();
        j["battery"] = x.get_battery();
        j["ok"] = x.get_ok();
    }
}

다른 언어로 JSON 변환