JSON 转 C++ 工具

根据 JSON 样例生成带 nlohmann/json 序列化函数的 C++ 类。

从 JSON 生成适用于 nlohmann/json 的 C++ 类

C++ 没有内置的 JSON 支持,而流行的 nlohmann/json 库要实现自动转换,需要为每个类型提供 from_json 和 to_json 函数。本工具会生成一个头文件,为每个对象声明一个类,包含私有成员、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,用于可选字段;如果你的 JSON 中没有可选字段,可以删除这条 include。
需要哪个 C++ 标准?
nlohmann/json 需要 C++11 或更高版本。除上述库之外,生成的头文件只使用标准库类型。
可以修改 quicktype 命名空间吗?
可以。把 namespace quicktype 改成你自己的命名空间即可;只要 from_json 和 to_json 与类处于同一命名空间,就能通过参数依赖查找(ADL)找到它们。

示例:JSON 转 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 转换为其他语言