diff --git a/README.md b/README.md index 469372c..f0d424a 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ -# C结构体与 JSON 快速互转库 +# C&C++结构体与 JSON 快速互转库 --- ## struct2json -[struct2json](https://github.com/armink/struct2json) 是一个开源的C结构体与 JSON 快速互转库,它可以快速实现 **结构体对象** 与 **JSON 对象** 之间序列化及反序列化要求。快速、简洁的 API 设计,大大降低直接使用 JSON 解析库来实现此类功能的代码复杂度。 +[struct2json](https://github.com/armink/struct2json) 是一个开源的C&C++结构体与 JSON 快速互转库,它可以快速实现 **结构体对象** 与 **JSON 对象** 之间序列化及反序列化要求。快速、简洁的 API 设计,大大降低直接使用 JSON 解析库来实现此类功能的代码复杂度。 ## 起源 -把面向对象设计应用到C语言中,是当下很流行的设计思想。由于C语言中没有类,所以一般使用结构体 `struct` 充当类,那么结构体变量就是对象。有了对象之后,很多时候需要考虑对象的序列化及反序列化问题。C语言不像很多高级语言拥有反射等机制,使得对象序列化及反序列化被原生的支持。 +C&C++对象的序列化及反序列化问题解决方案(由于C语言中没有类,所以一般使用结构体 `struct` 充当类,那么结构体变量就是对象)。 +C&C++语言不像很多高级语言拥有反射等机制,使得对象序列化及反序列化被原生的支持。 +对于C&C++语言来说,序列化为 JSON 字符串是个不错的选择,所以就得使用 [cJSON](https://github.com/kbranigan/cJSON) 这类 JSON 解析库,但是使用后的代码冗余且逻辑性差,所以萌生对cJSON库进行二次封装,实现一个 struct 与 JSON 之间快速互转的库。 struct2json 就诞生于此。下面是 struct2json 主要使用场景: -对于C语言来说,序列化为 JSON 字符串是个不错的选择,所以就得使用 [cJSON](https://github.com/kbranigan/cJSON) 这类 JSON 解析库,但是使用后的代码冗余且逻辑性差,所以萌生对cJSON库进行二次封装,实现一个 struct 与 JSON 之间快速互转的库。 struct2json 就诞生于此。下面是 struct2json 主要使用场景: - -- **持久化** :结构体对象序列化为 JSON 对象后,可直接保存至文件、Flash,实现对结构体对象的掉电存储; -- **通信** :高级语言对JSON支持的很友好,例如: Javascript、Groovy 就对 JSON 具有原生的支持,所以 JSON 也可作为C语言与其他语言软件之间的通信协议格式及对象传递格式; +- **持久化** :结构体对象序列化为 JSON 对象后,可直接保存至文件、Flash,实现对结构体对象的持久化存储; +- **通信** :高级语言对JSON支持的很友好,例如: Javascript、Groovy 就对 JSON 具有原生的支持,所以 JSON 也可作为C&C++语言与其他语言软件之间的通信协议格式及对象传递格式; - **可视化** :序列化为 JSON 后的对象,可以更加直观的展示到控制台或者 UI 上,可用于产品调试、产品二次开发等场景; ## 如何使用 @@ -50,12 +50,15 @@ typedef struct { |:-----:|:-----:| |![JSON转结构体-使用前](https://git.oschina.net/Armink/struct2json/raw/master/docs/zh/images/not_use_struct2json_for_json.png)| ![JSON转结构体-使用后](https://git.oschina.net/Armink/struct2json/raw/master/docs/zh/images/used_struct2json_for_json.png)| -### V2.0版本新增功能【yuxuebao】 -#### 1) 更新cJSON库至1.7.12版本,并扩充实现,支持int64 (long long)类型数据。PS:cJSON原来int64类型以double方式处理,如果超过16位会有精度损失。 +### V2.0版本新增功能【yuxuebao@msn.com】 +#### 1) 更新cJSON库至1.7.14版本,并扩充实现,支持int64 (long long)类型数据。PS:cJSON原来int64类型以double方式处理,如果超过16位会有精度损失。 #### 2) 扩展struct2json功能,增加支持结构体内包含结构体成员,支持包含数组成员。 #### 3) 增加struct2json 结构体与JSON转换代码自动生成的Python脚本,支持从头文件中提取结构体定义,并根据结构体定义自动生成结构体与JSON互转代码,并提供相关示例。 -### V2.0 使用说明: +### V2.1版本新增功能【yuxuebao@msn.com】 +#### 1) 扩展struct2json功能,增加支持C++结构体,支持string,bool,wchar_t类型成员和数组。 + +### V2.x 使用说明: #### 1) 提取结构体定义: 将头文件(eg:mc_usr_def.h)放在demo\inc目录下; 执行generate_struct_defination.py,生成struct_defination.txt; @@ -65,10 +68,12 @@ typedef struct { 支持的数组类型:支持基本类型一维数组,结构体一维数组,字符二维数组(字符串数组) #### 3) 测试结构体与JSON转换: cd demo - 编译测试代码,gcc ../cJSON/cJSON.c ../struct2json/src/*.c ./*.c -I ../cJSON/ -I ../struct2json/inc/ -lm -DDEBUGS2J -g -o tests2j + 编译测试代码, + V2.0: gcc ../cJSON/cJSON.c ../struct2json/src/*.c ./*.c -I ../cJSON/ -I ../struct2json/inc/ -lm -g -DDEBUGS2J -o tests2j + V2.1+: g++ ../cJSON/cJSON.c ../struct2json/src/*.c ./*.c -I ../cJSON/ -I ../struct2json/inc/ -fpermissive -lm -g -DDEBUGS2J -o tests2j 测试 ./tests2j 查看output输出和生成的JSON样例文件struct_defination.json; - 预期输出:*:strcmp:0 *:strcmp:0 *:json_cmp:1 + 预期输出:*:strcmp:0 *:strcmp:0 *:json_cmp:1 欢迎大家 **fork and pull request**([Github](https://github.com/armink/struct2json)|[OSChina](http://git.oschina.net/armink/struct2json)|[Coding](https://coding.net/u/armink/p/struct2json/git)) 。如果觉得这个开源项目很赞,可以点击[项目主页](https://github.com/armink/struct2json) 右上角的**Star**,同时把它推荐给更多有需要的朋友。 diff --git a/demo/error_print.txt b/demo/error_print.txt index d8f0ca4..9a4ef24 100644 --- a/demo/error_print.txt +++ b/demo/error_print.txt @@ -1,9 +1,11 @@ +struct_para_json2bin(CppStructInfoT,bin_para,type,value) struct_para_json2bin(McUsrInfoT,bin_para,type,value) struct_para_json2bin(McBaseOrdrT,bin_para,type,value) struct_para_json2bin(McBaseOrdrArrayT,bin_para,type,value) struct_para_json2bin(McOcoBaseOrdrT,bin_para,type,value) ************************************* +struct_para_bin2json(CppStructInfoT,bin_para,type,json_para) struct_para_bin2json(McUsrInfoT,bin_para,type,json_para) struct_para_bin2json(McBaseOrdrT,bin_para,type,json_para) struct_para_bin2json(McBaseOrdrArrayT,bin_para,type,json_para) diff --git a/demo/generate_s2j_code.py b/demo/generate_s2j_code.py index d2bcdfe..edee164 100644 --- a/demo/generate_s2j_code.py +++ b/demo/generate_s2j_code.py @@ -72,10 +72,10 @@ #print(array_para_name_size) para_name = para_name.split("[")[0] s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_array_element(json_obj_, struct_obj_, int, "+ para_name + ","+ array_para_name_size+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_array_element(struct_obj_,json_obj, int, "+para_name + ");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_array_element(struct_obj_,json_obj, int, "+ para_name + ");\n\t" else: - s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, "+para_name+");\n\t" - j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, int, "+para_name+");\n\t" + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, "+ para_name+");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, int, "+ para_name+");\n\t" elif para_type.find("enum")!=-1 or para_type.find("CbT")!=-1: # enum或函数指针(根据实际命名规范识别) #print(para_type) if "[" in para_name: @@ -85,30 +85,44 @@ #print(array_para_name_size) para_name = para_name.split("[")[0] s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_array_element(json_obj_, struct_obj_, int, "+ para_name + ","+ array_para_name_size+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_array_element(struct_obj_,json_obj, int, "+para_name + ");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_array_element(struct_obj_,json_obj, int, "+ para_name + ");\n\t" else: - s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, "+para_name+");\n\t" - j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, int, "+para_name+");\n\t" + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, "+ para_name+");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, int, "+ para_name+");\n\t" + elif para_type in ("string","std::string"): #c++ std::string + if "[" in para_name: # 处理c++ std::string数组的情况 + #print(para_name) + left_symbol = para_name.find("[") # 找到[位置 + right_symbol = para_name.find("]") # 找到]位置 + array_para_name_size = para_name[left_symbol+1:right_symbol] + #print(array_para_name_size) + para_name = para_name.split("[")[0] + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_array_element(json_obj_, struct_obj_, stdstring, "+ para_name + ","+ array_para_name_size+");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_array_element(struct_obj_,json_obj, stdstring, "+ para_name + ");\n\t" + else: + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, stdstring, " + para_name + ");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, stdstring, " + para_name + ");\n\t" else: #基本类型 - if para_type in ("char","unsigned char","signed char","int","unsigned","unsigned int","signed int","short","unsigned short","signed short","long","unsigned long","signed long","long long","unsigned long long","signed long long","BOOL","bool","size_t","uint8_t","uint16_t","uint32_t","uint64_t","int8_t","int16_t","int32_t","int64_t","uint8","uint16","uint32","uint64","int8","int16","int32","int64","uint_fast64_t","__int128_t","__uint128_t","float","double","long double"): + if para_type in ("bool", "wchar_t", "char","unsigned char","signed char","int","unsigned","unsigned int","signed int","short","unsigned short","signed short","long","unsigned long","signed long","long long","unsigned long long","signed long long","BOOL","bool","size_t","uint8_t","uint16_t","uint32_t","uint64_t","int8_t","int16_t","int32_t","int64_t","uint8","uint16","uint32","uint64","int8","int16","int32","int64","uint_fast64_t","__int128_t","__uint128_t","float","double","long double"): if para_type in ("float","double","long double","__int128_t","__uint128_t"): #浮点型、128位整型 if "[" in para_name: #print(para_name) left_symbol = para_name.find("[") # 找到[位置 right_symbol = para_name.find("]") # 找到]位置 array_para_name_size = para_name[left_symbol+1:right_symbol] + #print(array_para_name_size) para_name = para_name.split("[")[0] s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_array_element(json_obj_, struct_obj_, double, "+ para_name + ","+ array_para_name_size+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_array_element(struct_obj_,json_obj, double, "+para_name + ");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_array_element(struct_obj_,json_obj, double, "+ para_name + ");\n\t" else: - s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, double, "+para_name+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_basic_element(struct_obj_,json_obj, double, "+para_name+");\n\t" + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, double, "+ para_name+");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, double, "+ para_name+");\n\t" elif para_type =="char" : # 字符串 if "[" in para_name: para_name_item = para_name.split("[") if len(para_name_item)==2: # 处理字符数组的情况,只取名字,舍弃中括号部分 para_name = para_name_item[0] - s2j_code_str_concat = s2j_code_str_concat+ "s2j_json_set_basic_element(json_obj_, struct_obj_, string, " + para_name + ");\n\t" + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, string, " + para_name + ");\n\t" j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, string, " + para_name + ");\n\t" elif len(para_name_item)==3: # 处理二维字符数组的情况 para_name = para_name_item[0] @@ -116,7 +130,7 @@ right_symbol = para_name_item[1].find("]") # 找到]位置 array_para_name_size = para_name_item[1][0:right_symbol] s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_array_element(json_obj_, struct_obj_, string, "+ para_name + ","+ array_para_name_size+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_array_element(struct_obj_,json_obj, string, "+para_name + ");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_array_element(struct_obj_,json_obj, string, "+ para_name + ");\n\t" else: s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, " + para_name + ");\n\t" j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, int, " + para_name + ");\n\t" @@ -129,10 +143,10 @@ #print(array_para_name_size) para_name = para_name.split("[")[0] s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_array_element(json_obj_, struct_obj_, int, "+ para_name + ","+ array_para_name_size+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_array_element(struct_obj_,json_obj, int, "+para_name + ");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_array_element(struct_obj_,json_obj, int, "+ para_name + ");\n\t" else: - s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, "+para_name+");\n\t" - j2s_code_str_concat = j2s_code_str_concat +"s2j_struct_get_basic_element(struct_obj_,json_obj, int, "+para_name+");\n\t" + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_basic_element(json_obj_, struct_obj_, int, "+ para_name+");\n\t" + j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_basic_element(struct_obj_,json_obj, int, "+ para_name+");\n\t" else: #结构体类型的参数 if "[" in para_name: # usrDefLst[MAX_LIST_MEM_TYPE] @@ -143,7 +157,7 @@ s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_struct_array_element_by_func(json_obj_, struct_obj_, "+ para_type +","+para_name+ ","+list_size+");\n\t" j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_struct_array_element_by_func(struct_obj_, json_obj, "+ para_type +","+para_name+");\n\t" else: - s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_struct_element_by_func(json_obj_, struct_obj_, "+ para_type +","+para_name+ ");\n\t" + s2j_code_str_concat = s2j_code_str_concat + "s2j_json_set_struct_element_by_func(json_obj_, struct_obj_, " + para_type +","+para_name+ ");\n\t" j2s_code_str_concat = j2s_code_str_concat + "s2j_struct_get_struct_element_by_func(struct_obj_, json_obj, " + para_type + "," + para_name + ");\n\t" s2j_code_str_concat_return = s2j_code_str_concat_return + s2j_code_str_concat # #"return json_obj_;\n}" @@ -199,13 +213,25 @@ #include "my_struct_2_json.inc" #include "my_struct_2_json.h" - #ifdef __cplusplus extern "C" { #endif """ void_main_header = r""" +#ifdef DEBUGS2J + + int s2j_test(void) + { +#ifdef __cplusplus + S2jHook s2jHookCpp = { + .malloc_fn = ::operator new, + .free_fn = ::operator delete, + }; + + s2j_init(&s2jHookCpp); +#endif + char file_name[] = "struct_defination.json"; FILE *fp; @@ -284,7 +310,7 @@ } #endif /* end of __cplusplus */ """ -str_return = head_str + return_code + "#ifdef DEBUGS2J \n int s2j_test(void)\n" +" {\n\t" + void_main_header + str_s2j_test + str_s2j_test_tail + str_s2j_test2_header + str_s2j_test2 + void_main_tail +str_return = head_str + return_code + "\n\t" + void_main_header + str_s2j_test + str_s2j_test_tail + str_s2j_test2_header + str_s2j_test2 + void_main_tail #print(str_return) error_return = error_print_json2bin + "\n" + "*************************************" + "\n" + error_print_bin2json diff --git a/demo/inc/mc_usr_def.h b/demo/inc/mc_usr_def.h index 4cb0b33..0713484 100644 --- a/demo/inc/mc_usr_def.h +++ b/demo/inc/mc_usr_def.h @@ -16,28 +16,22 @@ example #include /* define string handling functions */ #ifdef __cplusplus -extern "C" { +#include +typedef struct CppStructInfoS +{ + std::string string1; + std::string stringArray2[2]; + bool b1; + bool bArray2[2]; + wchar_t wc1; + wchar_t wcArray[2]; +} CppStructInfoT, *pCppStructInfoT; #endif +#ifdef __cplusplus +extern "C" { +#endif -/***************************************************************************** - ** - ** Type Defination - ** - *****************************************************************************/ - - -/***************************************************************************** - ** - ** Macro - ** - *****************************************************************************/ - -/****************************************************************************** - ** - ** Structure - ** - ******************************************************************************/ typedef int int32; typedef long long int64; diff --git a/demo/main.c b/demo/main.c index 048941b..ad28c40 100644 --- a/demo/main.c +++ b/demo/main.c @@ -31,10 +31,18 @@ #include #ifdef DEBUGS2J +#ifdef __cplusplus +extern "C" { extern int s2j_test(void); extern int s2j_test2(void); +} +#else +extern int s2j_test(void); +extern int s2j_test2(void); +#endif #endif// DEBUGS2J +#ifndef __cplusplus typedef struct { char name[16]; } Hometown; @@ -104,8 +112,10 @@ static cJSON *struct_to_json(void* struct_obj) { /* return Student JSON object pointer */ return json_student; } +#endif int main(void) { +#ifndef __cplusplus static Student orignal_student_obj = { .id = 24, .weight = 71.2, @@ -128,6 +138,7 @@ int main(void) { s2j_delete_json_obj(json_student); s2j_delete_struct_obj(converted_student_obj); +#endif #ifdef DEBUGS2J s2j_test(); @@ -136,3 +147,4 @@ int main(void) { return 0; } + diff --git a/demo/my_struct_2_json.c b/demo/my_struct_2_json.c index 0398a3e..2497b0c 100644 --- a/demo/my_struct_2_json.c +++ b/demo/my_struct_2_json.c @@ -2,11 +2,48 @@ #include "my_struct_2_json.inc" #include "my_struct_2_json.h" - #ifdef __cplusplus extern "C" { #endif - + +#ifdef __cplusplus +#if 0 +typedef struct CppStructInfoS +{ + std::string string1; + std::string stringArray2[2]; + bool b1; + bool bArray2[2]; + wchar_t wc1; + wchar_t wcArray[2]; +} CppStructInfoT, *pCppStructInfoT; +#endif +cJSON *struct_to_json_CppStructInfoT(void* struct_obj) +{ + s2j_create_json_obj(json_obj_); + CppStructInfoT *struct_obj_ = (CppStructInfoT *)struct_obj; + s2j_json_set_basic_element(json_obj_, struct_obj_, stdstring, string1); + s2j_json_set_array_element(json_obj_, struct_obj_, stdstring, stringArray2,2); + s2j_json_set_basic_element(json_obj_, struct_obj_, int, b1); + s2j_json_set_array_element(json_obj_, struct_obj_, int, bArray2,2); + s2j_json_set_basic_element(json_obj_, struct_obj_, int, wc1); + s2j_json_set_array_element(json_obj_, struct_obj_, int, wcArray,2); + return json_obj_; +} + +void *json_to_struct_CppStructInfoT(cJSON* json_obj) +{ + s2j_create_struct_obj(struct_obj_, CppStructInfoT); + s2j_struct_get_basic_element(struct_obj_,json_obj, stdstring, string1); + s2j_struct_get_array_element(struct_obj_,json_obj, stdstring, stringArray2); + s2j_struct_get_basic_element(struct_obj_,json_obj, int, b1); + s2j_struct_get_array_element(struct_obj_,json_obj, int, bArray2); + s2j_struct_get_basic_element(struct_obj_,json_obj, int, wc1); + s2j_struct_get_array_element(struct_obj_,json_obj, int, wcArray); + return struct_obj_; +} +#endif + #if 0 typedef struct McUsrInfoS { @@ -159,22 +196,36 @@ void *json_to_struct_McOcoBaseOrdrT(cJSON* json_obj) s2j_struct_get_basic_element(struct_obj_,json_obj, int, pUsrDef); return struct_obj_; } -#ifdef DEBUGS2J + + +#ifdef DEBUGS2J + int s2j_test(void) { - +#ifdef __cplusplus + S2jHook s2jHookCpp = { + .malloc_fn = ::operator new, + .free_fn = ::operator delete, + }; + + s2j_init(&s2jHookCpp); +#endif + char file_name[] = "struct_defination.json"; FILE *fp; fp = fopen(file_name, "w"); if (NULL == fp) return 1; - fprintf(fp,"{\n\t\"struct\": [\n\t\t{\n\t\t\t\"type\": \"void*\",\n\t\t\t\"value\": null\n\t\t}"); + fprintf(fp,"{\n\t\"struct\": [\n\t\t{\n\t\t\t\"type\": \"void*\",\n\t\t\t\"value\": null\n\t\t}"); +#ifdef __cplusplus + TEST_S2J_STRUCT(CppStructInfoT, 0 , fp); +#endif TEST_S2J_STRUCT(McUsrInfoT, 0 , fp); TEST_S2J_STRUCT(McBaseOrdrT, 0 , fp); TEST_S2J_STRUCT(McBaseOrdrArrayT, 0 , fp); TEST_S2J_STRUCT(McOcoBaseOrdrT, 0 , fp); - + fprintf(fp,"\n\t]\n}"); fclose(fp); return 0; @@ -214,11 +265,14 @@ void *json_to_struct_McOcoBaseOrdrT(cJSON* json_obj) printf("\nsize:\n%d\n",array_size); int i = 0; \ +#ifdef __cplusplus + TEST_S2J_JSON(CppStructInfoT, array_size); +#endif TEST_S2J_JSON(McUsrInfoT, array_size); TEST_S2J_JSON(McBaseOrdrT, array_size); TEST_S2J_JSON(McBaseOrdrArrayT, array_size); TEST_S2J_JSON(McOcoBaseOrdrT, array_size); - + fclose(fp); free(p); return 0; @@ -229,4 +283,4 @@ void *json_to_struct_McOcoBaseOrdrT(cJSON* json_obj) #ifdef __cplusplus } -#endif /* end of __cplusplus */ \ No newline at end of file +#endif /* end of __cplusplus */ diff --git a/demo/my_struct_2_json.h b/demo/my_struct_2_json.h index 5547764..8775c41 100644 --- a/demo/my_struct_2_json.h +++ b/demo/my_struct_2_json.h @@ -2,6 +2,11 @@ extern "C" { #endif +#ifdef __cplusplus +cJSON *struct_to_json_CppStructInfoT(void* struct_obj); + +void *json_to_struct_CppStructInfoT(cJSON* json_obj); +#endif cJSON *struct_to_json_McUsrInfoT(void* struct_obj); void *json_to_struct_McUsrInfoT(cJSON* json_obj); @@ -17,7 +22,7 @@ void *json_to_struct_McBaseOrdrArrayT(cJSON* json_obj); cJSON *struct_to_json_McOcoBaseOrdrT(void* struct_obj); void *json_to_struct_McOcoBaseOrdrT(cJSON* json_obj); - + #ifdef __cplusplus } -#endif /* end of __cplusplus */ \ No newline at end of file +#endif /* end of __cplusplus */ diff --git a/demo/my_struct_2_json.inc b/demo/my_struct_2_json.inc index 043ad43..e388eda 100644 --- a/demo/my_struct_2_json.inc +++ b/demo/my_struct_2_json.inc @@ -27,7 +27,7 @@ */ /* -gcc ../cJSON/cJSON.c ../struct2json/src/*.c ./*.c -I ../cJSON/ -I ../struct2json/inc/ -lm -DDEBUGS2J -g -o tests2j +g++ ../cJSON/cJSON.c ../struct2json/src/*.c ./*.c -I ../cJSON/ -I ../struct2json/inc/ -fpermissive -lm -g -DDEBUGS2J -o tests2j */ @@ -66,7 +66,31 @@ do\ #ifdef DEBUGS2J - +#ifdef __cplusplus +#define TEST_S2J_STRUCT(type, value, file) \ + type struct_obj##type; \ + cJSON *json_obj##type = struct_to_json_##type(&struct_obj##type); \ + char* str_json##type = cJSON_Print(json_obj##type); \ + printf("s2j:\n%s: %s\n",#type, str_json##type); \ + fprintf(file,",\n\t\t{\n\t\t\t\"type\": \"%s\",\n\t\t\t\"value\": %s\n\t\t}", #type, str_json##type); \ + cJSON *json_obj1##type =cJSON_Parse(str_json##type); \ + cJSON_bool json_cmp1##type = cJSON_Compare(json_obj ##type, json_obj1##type, 1); \ + printf("%s:json_cmp1:%d\n\n\n",#type, json_cmp1##type); \ + type *p_struct_obj##type =(type *)json_to_struct_##type(json_obj1##type); \ + cJSON *json_obj2##type = struct_to_json_##type(p_struct_obj##type); \ + char* str_json2##type = cJSON_Print(json_obj2##type); \ + printf("s2j2s2j:\n%s: %s\n",#type, str_json2##type); \ + int str_cmp##type = strcmp(str_json##type, str_json2##type); \ + printf("\n%s:strcmp:%d\n",#type, str_cmp##type); \ + cJSON_bool json_cmp2##type = cJSON_Compare(json_obj##type, json_obj2##type, 1); \ + printf("%s:json_cmp2:%d\n\n\n",#type, json_cmp2##type); \ + free(str_json##type); \ + free(str_json2##type); \ + s2j_delete_struct_obj(p_struct_obj##type); \ + s2j_delete_json_obj(json_obj##type); \ + s2j_delete_json_obj(json_obj1##type); \ + s2j_delete_json_obj(json_obj2##type); +#else #define TEST_S2J_STRUCT(type, value, file) \ type struct_obj##type; \ memset(&struct_obj##type, value, sizeof(type)); \ @@ -92,8 +116,8 @@ do\ s2j_delete_struct_obj(p_struct_obj##type); \ s2j_delete_json_obj(json_obj##type); \ s2j_delete_json_obj(json_obj1##type); \ - s2j_delete_json_obj(json_obj2##type); \ - + s2j_delete_json_obj(json_obj2##type); +#endif #define TEST_S2J_JSON(type, size) \ cJSON *json_struct_##type = NULL; \ diff --git a/demo/struct_defination.json b/demo/struct_defination.json index 7f345f3..cf51550 100644 --- a/demo/struct_defination.json +++ b/demo/struct_defination.json @@ -1,140 +1,88 @@ { - "struct": [ - { - "type": "void*", - "value": null - }, - { - "type": "McUsrInfoT", - "value": { - "pInt": 0, - "pIntArray": [ - 0, - 0 - ], - "fun": 0, - "funArray": [ - 0, - 0 - ], - "day1": 0, - "day2": 0, - "day2Array": [ - 0, - 0 - ], - "id": 0, - "idArray": [ - 0, - 0 - ], - "usrType": 0, - "usrName": "", - "usrNameArray": [ - "", - "" - ], - "usrSqno": 0, - "ussSqnoArray": [ - 0, - 0 - ], - "jobSqno": 0, - "jobSqnoArray": [ - 0, - 0 - ], - "rate": 0, - "rateArray": [ - 0, - 0 - ], - "price": 0, - "priceArray": [ - 0, - 0 - ] - } - }, - { - "type": "McBaseOrdrT", - "value": { - "taskSqno": 0, - "taskSqnoArray": [ - 0, - 0 - ], - "price": 0, - "priceArray": [ - 0, - 0 - ] - } - }, - { - "type": "McBaseOrdrArrayT", - "value": { - "mcBaseOrdrArray": [ - { - "taskSqno": 0, - "taskSqnoArray": [ - 0, - 0 - ], - "price": 0, - "priceArray": [ - 0, - 0 - ] - }, - { - "taskSqno": 0, - "taskSqnoArray": [ - 0, - 0 - ], - "price": 0, - "priceArray": [ - 0, - 0 - ] - } - ] - } - }, - { - "type": "McOcoBaseOrdrT", - "value": { - "mcBaseOrdrAry": { - "mcBaseOrdrArray": [ - { - "taskSqno": 0, - "taskSqnoArray": [ - 0, - 0 - ], - "price": 0, - "priceArray": [ - 0, - 0 - ] - }, - { - "taskSqno": 0, - "taskSqnoArray": [ - 0, - 0 - ], - "price": 0, - "priceArray": [ - 0, - 0 - ] - } - ] - }, - "pUsrDef": 0 - } - } - ] + "struct": [ + { + "type": "void*", + "value": null + }, + { + "type": "CppStructInfoT", + "value": { + "string1": "", + "stringArray2": ["", ""], + "b1": 224, + "bArray2": [146, 64], + "wc1": 0, + "wcArray": [607207720, 32765] +} + }, + { + "type": "McUsrInfoT", + "value": { + "pInt": 3399988123389603631, + "pIntArray": [3399988123389603631, 0], + "fun": 0, + "funArray": [-72057594037927936, 0], + "day1": 0, + "day2": 1073741824, + "day2Array": [0, 0], + "id": 47, + "idArray": [47, 47], + "usrType": 47, + "usrName": "///////", + "usrNameArray": ["////", ""], + "usrSqno": 0, + "ussSqnoArray": [0, -16777216], + "jobSqno": 0, + "jobSqnoArray": [0, 0], + "rate": 0, + "rateArray": [0, 0], + "price": 0, + "priceArray": [0, 0] +} + }, + { + "type": "McBaseOrdrT", + "value": { + "taskSqno": 1, + "taskSqnoArray": [0, 32703], + "price": 0, + "priceArray": [6.93967752719276e-310, 6.93967703304213e-310] +} + }, + { + "type": "McBaseOrdrArrayT", + "value": { + "mcBaseOrdrArray": [{ + "taskSqno": 24781, + "taskSqnoArray": [64, 0], + "price": 2.09089371825049e-317, + "priceArray": [6.93967765101035e-310, 0] + }, { + "taskSqno": 0, + "taskSqnoArray": [0, 0], + "price": 0, + "priceArray": [0, 1.3906499416489327e-309] + }] +} + }, + { + "type": "McOcoBaseOrdrT", + "value": { + "mcBaseOrdrAry": { + "mcBaseOrdrArray": [{ + "taskSqno": 0, + "taskSqnoArray": [0, 0], + "price": 0, + "priceArray": [0, 0] + }, { + "taskSqno": 0, + "taskSqnoArray": [0, 0], + "price": 0, + "priceArray": [0, 0] + }] + }, + "pUsrDef": 0 +} + } + ] } \ No newline at end of file diff --git a/demo/struct_defination.txt b/demo/struct_defination.txt index ac080e7..3eb9645 100644 --- a/demo/struct_defination.txt +++ b/demo/struct_defination.txt @@ -1,4 +1,14 @@ +typedef struct CppStructInfoS +{ + std::string string1; + std::string stringArray2[2]; + bool b1; + bool bArray2[2]; + wchar_t wc1; + wchar_t wcArray[2]; +} CppStructInfoT, *pCppStructInfoT; + typedef struct McUsrInfoS { int *pInt; diff --git a/demo/tests2j b/demo/tests2j index ba710c6..ed7e311 100644 Binary files a/demo/tests2j and b/demo/tests2j differ diff --git a/struct2json/inc/s2j.h b/struct2json/inc/s2j.h index d1b1f9f..6c73146 100644 --- a/struct2json/inc/s2j.h +++ b/struct2json/inc/s2j.h @@ -38,7 +38,8 @@ extern "C" { #endif /* struct2json software version number */ -#define S2J_SW_VERSION "2.0.0" + +#define S2J_SW_VERSION "2.1.0" /* Create JSON object */ diff --git a/struct2json/inc/s2jdef.h b/struct2json/inc/s2jdef.h index 63b6e93..9d8bd26 100644 --- a/struct2json/inc/s2jdef.h +++ b/struct2json/inc/s2jdef.h @@ -32,6 +32,10 @@ #include "cJSON.h" #include +#ifdef __cplusplus +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -63,6 +67,12 @@ typedef struct { json_temp = cJSON_GetObjectItem(from_json, #_element); \ if (json_temp) strncpy((to_struct)->_element, json_temp->valuestring,sizeof((to_struct)->_element)-1); +#ifdef __cplusplus +#define S2J_STRUCT_GET_stdstring_ELEMENT(to_struct, from_json, _element) \ + json_temp = cJSON_GetObjectItem(from_json, #_element); \ + if (json_temp) (to_struct)->_element.assign(json_temp->valuestring); +#endif + #define S2J_STRUCT_GET_string_ELEMENT_EX(to_struct, from_json, _element, _defval) \ { \ if (from_json) { \ @@ -74,6 +84,19 @@ typedef struct { } \ } +#ifdef __cplusplus +#define S2J_STRUCT_GET_stdstring_ELEMENT_EX(to_struct, from_json, _element, _defval) \ + { \ + if (from_json) { \ + json_temp = cJSON_GetObjectItem(from_json, #_element); \ + if (json_temp) (to_struct)->_element.assign( json_temp->valuestring); \ + else (to_struct)->_element.assign(1, _defval); \ + } else { \ + (to_struct)->_element.assign(1, _defval); \ + } \ + } +#endif + #define S2J_STRUCT_GET_double_ELEMENT(to_struct, from_json, _element) \ json_temp = cJSON_GetObjectItem(from_json, #_element); \ if (json_temp) (to_struct)->_element = json_temp->valuedouble; @@ -95,6 +118,11 @@ typedef struct { #define S2J_STRUCT_ARRAY_GET_string_ELEMENT(to_struct, from_json, _element, index) \ strncpy((to_struct)->_element[index], from_json->valuestring,sizeof((to_struct)->_element[0])-1); +#ifdef __cplusplus +#define S2J_STRUCT_ARRAY_GET_stdstring_ELEMENT(to_struct, from_json, _element, index) \ + (to_struct)->_element[index].assign( from_json->valuestring); +#endif + #define S2J_STRUCT_ARRAY_GET_double_ELEMENT(to_struct, from_json, _element, index) \ (to_struct)->_element[index] = from_json->valuedouble; @@ -109,6 +137,12 @@ typedef struct { if (from_json) strncpy((to_struct)->_element[index], from_json->valuestring,sizeof((to_struct)->_element[0])-1); \ else strncpy((to_struct)->_element[index], _defval,sizeof((to_struct)->_element[0])-1); +#ifdef __cplusplus +#define S2J_STRUCT_ARRAY_GET_stdstring_ELEMENT_EX(to_struct, from_json, _element, index, _defval) \ + if (from_json) (to_struct)->_element[index].assign( from_json->valuestring); \ + else (to_struct)->_element[index].assign(1, _defval); +#endif + #define S2J_STRUCT_ARRAY_GET_double_ELEMENT_EX(to_struct, from_json, _element, index, _defval) \ if (from_json) (to_struct)->_element[index] = from_json->valuedouble; \ else (to_struct)->_element[index] = _defval; @@ -126,6 +160,11 @@ typedef struct { (from_struct)->_element[sizeof((from_struct)->_element)-1] = '\0'; \ cJSON_AddStringToObject(to_json, #_element, (from_struct)->_element); +#ifdef __cplusplus +#define S2J_JSON_SET_stdstring_ELEMENT(to_json, from_struct, _element) \ + cJSON_AddStringToObject(to_json, #_element, (from_struct)->_element.c_str()); +#endif + #define S2J_JSON_ARRAY_SET_int_ELEMENT(to_json, from_struct, _element, index) \ cJSON_AddItemToArray(to_json, cJSON_CreateInt((from_struct)->_element[index])); @@ -136,6 +175,11 @@ typedef struct { (from_struct)->_element[index][sizeof((from_struct)->_element[0])-1] = '\0'; \ cJSON_AddItemToArray(to_json, cJSON_CreateString((from_struct)->_element[index])); +#ifdef __cplusplus +#define S2J_JSON_ARRAY_SET_stdstring_ELEMENT(to_json, from_struct, _element, index) \ + cJSON_AddItemToArray(to_json, cJSON_CreateString((from_struct)->_element[index].c_str())); +#endif + #define S2J_JSON_ARRAY_SET_ELEMENT(to_json, from_struct, type, _element, index) \ S2J_JSON_ARRAY_SET_##type##_ELEMENT(to_json, from_struct, _element, index) @@ -167,13 +211,24 @@ typedef struct { cJSON *child_json = cJSON_CreateObject(); \ if (child_json) cJSON_AddItemToObject(to_json, #_element, child_json); +#ifdef __cplusplus +#define S2J_CREATE_STRUCT_OBJECT(struct_obj, type) \ + cJSON *json_temp; \ + type *struct_obj = (type *) new type; +#else #define S2J_CREATE_STRUCT_OBJECT(struct_obj, type) \ cJSON *json_temp; \ type *struct_obj = (type *)s2jHook.malloc_fn(sizeof(type)); \ if (struct_obj) memset(struct_obj, 0, sizeof(type)); +#endif +#ifdef __cplusplus +#define S2J_DELETE_STRUCT_OBJECT(struct_obj) \ + delete struct_obj; +#else #define S2J_DELETE_STRUCT_OBJECT(struct_obj) \ s2jHook.free_fn(struct_obj); +#endif #define S2J_STRUCT_GET_BASIC_ELEMENT(to_struct, from_json, type, _element) \ S2J_STRUCT_GET_##type##_ELEMENT(to_struct, from_json, _element)