| name | meojson |
| description | meojson C++ JSON 库使用指南。用于 MaaFramework C++ 项目中的 JSON 解析、序列化、MEO_JSONIZATION、json::value 操作、ext::jsonization 自定义类型支持,以及 Custom 参数解析。 |
meojson 使用指南
meojson 是 MaaFramework 依赖中常用的 header-only C++ JSON 库。通常通过以下头文件引入:
#include <meojson/json.hpp>
核心类型
| 类型 | 说明 |
|---|
json::value | 通用 JSON 值:null / bool / number / string / array / object |
json::array | JSON 数组,包装 std::vector<json::value> |
json::object | JSON 对象,包装 std::map<std::string, json::value> |
解析
auto opt = json::parse(str);
auto file = json::open(path);
auto jsonc = json::parsec(str);
推荐安全模式:
template <typename T>
T ParseParam(const char* text)
{
if (text == nullptr || std::strlen(text) == 0) {
return T {};
}
auto opt = json::parse(text);
if (!opt) {
LogError << "failed to parse json param" << VAR(text);
return T {};
}
T result {};
if (!result.from_json(*opt)) {
LogError << "failed to deserialize json param" << VAR(text);
return T {};
}
return result;
}
避免:
json::parse(str).value_or(json::object {}).as<T>();
这会静默吞掉 parse 失败,并可能在 required 字段缺失时抛异常。
构造 JSON 值
json::value v1 = 42;
json::value v2 = "hello";
json::value v3 = true;
json::value v4 = nullptr;
json::array arr { 1, 2, "three" };
json::object obj {
{ "key1", "value1" },
{ "key2", 42 },
};
std::vector<int> vec = { 1, 2, 3 };
json::value v5 = vec;
std::map<std::string, int> map = { { "a", 1 } };
json::value v6 = map;
读取值
类型检查
v.is_null();
v.is_boolean();
v.is_number();
v.is_string();
v.is_array();
v.is_object();
v.is<int>();
直接访问
v.as_string();
v.as_string_view();
v.as_integer();
v.as_double();
v.as_boolean();
v.as_array();
v.as_object();
v.as<T>();
as_*() / as<T>() 类型不匹配时可能抛异常,只在确定数据合法时使用。
安全访问
auto name = v.find<std::string>("name");
if (name) {
}
std::string label = v.get("label", "default");
int count = v.get("config", "count", 0);
if (v.exists("key")) {
}
序列化
v.dumps();
v.dumps(4);
v.format();
写回 MaaFramework detail 的常见模式:
template <typename T>
void WriteJsonDetail(MaaStringBuffer* out_detail, const T& payload)
{
if (out_detail == nullptr) {
return;
}
const std::string json_text = json::value(payload).dumps();
MaaStringBufferSet(out_detail, json_text.c_str());
}
Object 合并
json::value merged = obj1 | obj2;
obj1 |= obj2;
MEO_JSONIZATION
MEO_JSONIZATION(fields...) 生成 to_json()、check_json()、from_json()。
struct LocateOutput {
int status = 0;
std::string message;
std::string map_name;
int x = 0;
int y = 0;
MEO_JSONIZATION(status, message, MEO_OPT map_name, MEO_OPT x, MEO_OPT y)
};
序列化:
json::value j = data;
反序列化推荐:
LocateOutput data {};
if (!data.from_json(j)) {
LogError << "failed to deserialize" << VAR(j);
}
MEO_OPT
默认字段都是 required。用 MEO_OPT 标记可选字段,缺失时保留默认值:
struct Options {
double threshold = 0.7;
bool enabled = true;
MEO_JSONIZATION(MEO_OPT threshold, MEO_OPT enabled)
};
每个可选字段都需要自己的 MEO_OPT。
MEO_KEY
当 JSON key 与 C++ 字段名不同,使用 MEO_KEY:
struct TemplateParam {
std::vector<std::string> template_;
MEO_JSONIZATION(MEO_KEY("template") template_)
};
与 MEO_OPT 组合时顺序通常为:
MEO_OPT MEO_KEY("default") default_
子宏
| 宏 | 生成内容 |
|---|
MEO_TOJSON(...) | to_json() |
MEO_FROMJSON(...) | from_json() |
MEO_CHECKJSON(...) | check_json() |
MEO_JSONIZATION(...) | 全部三个 |
ext::jsonization
对不拥有源码的类型,特化 json::ext::jsonization<T>:
namespace json::ext {
template <>
class jsonization<MyRect> {
public:
json::value to_json(const MyRect& rect) const
{
return json::array { rect.x, rect.y, rect.width, rect.height };
}
bool check_json(const json::value& value) const
{
return value.is<std::vector<int>>() && value.as_array().size() == 4;
}
bool from_json(const json::value& value, MyRect& rect) const
{
auto arr = value.as<std::vector<int>>();
rect = MyRect { arr[0], arr[1], arr[2], arr[3] };
return true;
}
};
}
Enum 反射
enum class MyEnum {
A,
B,
C,
MEOJSON_ENUM_RANGE(A, C)
};
json::value j = MyEnum::B;
MyEnum e = j.as<MyEnum>();
常见坑
json::parse 返回 std::optional,必须检查。
as_*() / as<T>() 类型不匹配时可能抛异常。
- 禁止
.value_or(...).as<T>() 静默吞解析错误。
char / wchar_t 构造被禁用,使用 std::string 或整数。
ext::jsonization 位于 json::ext 命名空间。
- 每个可选字段都需要自己的
MEO_OPT。
MEO_KEY 与 MEO_OPT 组合时注意顺序。
参考
详细 API 见 reference.md。