# x2struct **Repository Path**: cnull_project/x2struct ## Basic Information - **Project Name**: x2struct - **Description**: Convert between json string and c++ object. json字符串和c++结构体之间互相转换 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-12-19 - **Last Updated**: 2022-07-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README x2struct ==== * 用于在C++结构体和json/xml/json/libconfig之间互相转换 * json/xml只需要头文件, 无需编译库文件 * json缺省支持,其他的需要修改[config.h](config.h)开启相应功能 * 以下例子全部以json为例,其他的类似,具体可以参考[x2struct.hpp](x2struct.hpp)里面x2struct::X的api定义 ------ * [基本用法](#基本用法) * [必需节点](#必需节点) * [别名](#别名) * [继承](#继承) * [位域](#位域) * [条件加载](#条件加载) * [char数组](#char数组) * [检查是否存在](#检查是否存在) * [局部类](#局部类) * [自定义类型](#自定义类型) * [第三方类和结构体](#第三方类和结构体) * [格式化缩进](#格式化缩进) * [Qt支持](#qt支持) * [xml bson libconfig](#xml-bson-libconfig) * [生成Golang结构体](#生成golang结构体) * [重要说明](#重要说明) 基本用法 ---- ```C++ #include #include "x2struct/x2struct.hpp" // 包含这个头文件 using namespace std; struct User { int64_t id; string name; string mail; User(int64_t i=0, const string& n="", const string& m=""):id(i),name(n),mail(m){} XTOSTRUCT(O(id, name, mail)); // 添加宏定义XTOSTRUCT在结构体定义结尾 }; struct Group { string name; int64_t master; vector members; XTOSTRUCT(O(name, master, members)); // 添加宏定义XTOSTRUCT在结构体定义结尾 }; int main(int argc, char *argv[]) { Group g; g.name = "C++"; g.master = 2019; g.members.resize(2); g.members[0] = User(1, "Jack", "jack@x2struct.com"); g.members[1] = User(2, "Pony", "pony@x2struct.com"); string json = x2struct::X::tojson(g); // 结构体转json cout< vi; x2struct::X::loadjson("[1,2,3]", vi, false); // 直接加载vector cout< m; x2struct::X::loadjson("{\"1\":10, \"2\":20}", m, false); // 直接加载map cout< #include "x2struct/x2struct.hpp" using namespace std; struct Test { int64_t id; string name; XTOSTRUCT(M(id), O(name)); // "id"是必需节点,用M包含,"name"是可选节点,用"O"包含 }; int main(int argc, char *argv[]) { Test t; string json="{\"name\":\"Pony\"}"; x2struct::X::loadjson(json, t, false); // 这里将会抛异常,因为"id"是必需节点,但是json里面没有 return 0; } ``` 别名 ---- - 用于变量名和key名不一致的场景 - 用"A"包含需要设置别名的变量,"A"包含两个参数,参数1是变量名,参数2是别名信息 - 别名段的基本格式是"[type:]alias[,extension]", 别名信息可以包含多个别名段,别名段之间用空格隔开 - type的值可以是"json"/"xml"/"bson"/"config", 如果别名段没有type这个字段,则表示这个别名段对所有的type生效,例子: - "tid" 由于没有type,那么表示所有的type的别名都是"tid" - "tid json:xid" "tid"没指定type,xid指定了json,那么json用xid,其他的用tid - 扩展字段目前只支持"m",表示必需节点(缺省是可选) - 如果在json里面没有别名,依然会尝试变量名 - 结构体转json的时候,用别名 ``` C++ #include #include "x2struct/x2struct.hpp" using namespace std; struct Test { int64_t uid; string name; XTOSTRUCT(A(uid, "id"), O(name)); // "uid"的别名是"id" }; int main(int argc, char *argv[]) { Test t; string json="{\"id\":123, \"name\":\"Pony\"}"; x2struct::X::loadjson(json, t, false); cout< #include "x2struct/x2struct.hpp" using namespace std; struct P1 { string mail; XTOSTRUCT(O(mail)); }; struct P2 { int64_t version; XTOSTRUCT(O(version)); }; struct Test:public P1, public P2 { int64_t uid; string name; XTOSTRUCT(I(P1, P2), O(uid, name)); }; int main(int argc, char *argv[]) { Test t; string json="{\"mail\":\"pony@x2struct.com\", \"version\":2019, \"id\":123, \"name\":\"Pony\"}"; x2struct::X::loadjson(json, t, false); cout< #include "x2struct/x2struct.hpp" using namespace std; struct Test { int16_t ver:8; int16_t len:8; string name; XTOSTRUCT(B(ver, len), O(name)); }; int main(int argc, char *argv[]) { Test t; string json="{\"ver\":4, \"len\":20, \"name\":\"IPv4\"}"; x2struct::X::loadjson(json, t, false); cout< #include "x2struct/x2struct.hpp" using namespace std; struct Task { int id; string name; XTOSTRUCT(O(id, name)); }; struct Test { int tid; Task task; XTOSTRUCT(C(task), O(tid, task)); // 在XTOSTRUCT里面,task既包含在"C"里面,也包含在"O"里面 /* XTOSTRUCT_CONDITION 这个宏包含两个参数,一个类名,一个变量名 XTOSTRUCT_CONDITION 定义了一个函数,函数有一个变量,名为"obj"指向的是变量对应的xdoc "task"在json里面是一个数组,这里只加载那个XTOSTRUCT_CONDITION返回true的那个,这里当tid等于id时返回true */ XTOSTRUCT_CONDITION(Test, task) { int id; // only load the one that Task.id is equal to Test.tid return obj.convert("id", id)&&id==this->tid; } }; int main(int argc, char *argv[]) { string s = "{\"tid\":2019,\"task\":[{\"id\":2018,\"name\":\"hello\"},{\"id\":2019,\"name\":\"world\"}]}"; Test t; x2struct::X::loadjson(s, t, false); cout< #include "x2struct/x2struct.hpp" using namespace std; struct Test { int64_t id; string name; XTOSTRUCT(O(id, name)); }; int main(int argc, char *argv[]) { Test t; string json="{\"name\":\"Pony\"}"; x2struct::X::loadjson(json, t, false, true); // 如果需要用这个功能,第四个参数需要是true cout< #include "x2struct/x2struct.hpp" using namespace std; int main(int argc, char *argv[]) { struct Test { int64_t id; string name; XTOSTRUCT_NT(Json)(O(id, name)); }; Test t; string json="{\"id\":123, \"name\":\"Pony\"}"; x2struct::X::loadjson(json, t, false); cout< 完成自定义类型的定义 - 以下代码是一个IPv4的例子 ```C++ #include #include "x2struct/x2struct.hpp" using namespace std; // 只是一个范例,没做错误处理 struct _XIPv4 { uint32_t ip; // 实现format函数 std::string format() const { char buf[64]; int len = sprintf(buf, "%u.%u.%u.%u", ip>>24, 0xff&(ip>>16), 0xff&(ip>>8), 0xff&ip); return string(buf, len); } // 实现parse函数 void parse(const std::string& d) { uint32_t u[4]; sscanf(d.c_str(), "%u.%u.%u.%u", &u[0], &u[1], &u[2], &u[3]); ip = (u[0]<<24)+(u[1]<<16)+(u[2]<<8)+u[3]; } }; // typedef 定义 typedef x2struct::XType<_XIPv4> XIPv4; struct Test { XIPv4 ip; XIPv4 mask; XTOSTRUCT(O(ip, mask)); }; int main(int argc, char *argv[]) { Test t; // 在json里面自定义类型是string string json="{\"ip\":\"192.168.1.2\", \"mask\":\"255.255.255.0\"}"; x2struct::X::loadjson(json, t, false); cout< #include #include "x2struct/x2struct.hpp" using namespace std; /* struct timeval { time_t tv_sec; suseconds_t tv_usec; }; */ // timeval is thirdparty struct XTOSTRUCT_OUT(timeval, O(tv_sec, tv_usec)); struct T { int a; string b; timeval t; XTOSTRUCT(O(a, b, t)); }; int main(int argc, char *argv[]) { T t; T r; t.a = 123; t.b = "x2struct"; t.t.tv_sec = 888; t.t.tv_usec = 999; string s = x2struct::X::tojson(t); cout<,那么key需要用x+数字的方式,比如x100 - mongoxclient(https://github.com/xyz347/mongoxclient)是对mongo-cxx-driver的一个封装 生成Golang结构体 ---- - 用于将C++结构体转Golang结构体 - 需要定义宏XTOSTRUCT_GOCODE ```C++ // go.cpp // g++ -o t go.cpp -DXTOSTRUCT_GOCODE #include #include "x2struct/x2struct.hpp" using namespace std; struct Test { int64_t id; vector names; XTOSTRUCT(O(id, names)); }; int main(int argc, char *argv[]) { Test t; cout<