C语言结构体与json互转:struct2json

struct2json的库来自 <struct2json: C结构体与 JSON 快速互转库,快速实现C结构体的序列化及反序列化>    (该博主博客还有超多实用功能库!!!)

struct2json 是一个基于cJSON库开源的C结构体与 JSON 快速互转库,它可以快速实现 结构体对象 与 JSON 对象 之间序列化及反序列化要求。快速、简洁的 API 设计,大大降低直接使用 JSON 解析库来实现此类功能的代码复杂度

下面是 struct2json 主要使用场景:

  • 持久化 :结构体对象序列化为 JSON 对象后,可直接保存至文件、Flash,实现对结构体对象的掉电存储;
  • 通信 :高级语言对JSON支持的很友好,例如:Javascript、Groovy 就对 JSON 具有原生的支持,所以 JSON 也可作为C语言与其他语言软件之间的通信协议格式及对象传递格式;
  • 可视化 :序列化为 JSON 后的对象,可以更加直观的展示到控制台或者 UI 上,可用于产品调试、产品二次开发等场景;

 

注:目前主要初始化该库及cJSON库所需的内存管理方法。默认使用的 malloc free 作为内存管理方法,如果使用默认内存管理方式,无需初始化。

1.如果裸机下使用,则不需要重新初始化,因为裸机对内存分配、释放,是默认使用 malloc 及 free 作为内存管理方法。

2.如果使用操作系统,或其他平台,就要先了解使用的操作系统或平台,它对于内存分配、释放,使用的是什么函数?

3.举以下例子,在STM32的FreeRTOS下使用cJSON库,重新定义cJSON的内存分配、释放demo.

void Cjson_redefine_InitHooks(void) {

 

    cJSON_Hooks my_init_hook;

    my_init_hook.malloc_fn = pvPortMalloc;

    my_init_hook.free_fn = vPortFree;

    cJSON_InitHooks(&lele_init_hook);

}

注:cJSON库所需的内存管理方法,需要大量指针内存空间,在处理多级JSON嵌套、嵌套数组等等,如果芯片处理器的RAM不够,或者在操作系统分别的任务堆栈不够,回出现解析某些数据的时候直接返回空指针。

1.只要把当前任务的stacksz(注意它*4才是实际占用的字节数哦)设置到足够大就OK了。

2.我这里是1200,也就是4800字节,一般情况下的json参数设置也就够了。

  /* definition and creation of NetTask */

  osThreadDef(NetTask, StartNetTask, osPriorityNormal, 0, 1200);

  NetTaskHandle = osThreadCreate(osThread(NetTask), NULL);

 

如何使用struct2json?

1.如下声明了两个结构体,结构体 Hometown 是结构体 Student 的子结构体。

/* 籍贯 */

typedef struct {

    char name[16];

} Hometown;

 

/* 学生 */

typedef struct {

    uint8_t id;

    uint8_t score[8];

    char name[10];

    double weight;

    Hometown hometown;

} Student;

 

2.针对结构体内容,重新按照规则定义两个函数,分别将结构体对象序列化为 JSON 对象、将 JSON 对象反序列化为结构体对象。

static cJSON *struct_to_json(void* struct_obj) {

    Student *struct_student = (Student *)struct_obj;

 

    /* create Student JSON object */

    s2j_create_json_obj(json_student);

 

    /* serialize data to Student JSON object. */

    s2j_json_set_basic_element(json_student, struct_student, int, id);

    s2j_json_set_basic_element(json_student, struct_student, double, weight);

    s2j_json_set_array_element(json_student, struct_student, int, score, 8);

    s2j_json_set_basic_element(json_student, struct_student, string, name);

 

    /* serialize data to Student.Hometown JSON object. */

    s2j_json_set_struct_element(json_hometown, json_student, struct_hometown, struct_student, Hometown, hometown);

    s2j_json_set_basic_element(json_hometown, struct_hometown, string, name);

 

    /* return Student JSON object pointer */

    return json_student;

}

 

static void *json_to_struct(cJSON* json_obj) {

    /* create Student structure object */

    s2j_create_struct_obj(struct_student, Student);

 

    /* deserialize data to Student structure object. */

    s2j_struct_get_basic_element(struct_student, json_obj, int, id);

    s2j_struct_get_array_element(struct_student, json_obj, int, score);

    s2j_struct_get_basic_element(struct_student, json_obj, string, name);

    s2j_struct_get_basic_element(struct_student, json_obj, double, weight);

 

    /* deserialize data to Student.Hometown structure object. */

    s2j_struct_get_struct_element(struct_hometown, struct_student, json_hometown, json_obj, Hometown, hometown);

    s2j_struct_get_basic_element(struct_hometown, json_hometown, string, name);

 

    /* return Student structure object pointer */

    return struct_student;

}

 

3.stm32裸机下将结构体对象序列化为 JSON 对象demo。

int main(void) {

 

    static Student orignal_student_obj = {

            .id = 24,

            .weight = 71.2,

            .score = {1, 2, 3, 4, 5, 6, 7, 8},

            .name = "armink",

            .hometown.name = "China",

    };

 

  while (1)

  {

char                *out = NULL;

    cJSON *json_student = struct_to_json(&orignal_student_obj);        

out = cJSON_PrintUnformatted(json_student);  // second string print将JSON对象“无格式”打印输出

printf("%s\n", out);

vPortFree(out);// 其他操作系统,如freertos使用

    s2j_delete_json_obj(json_student);//记得释放内存,不然会溢出,宕机

HAL_Delay(1000);

   }

}

 

串口调试助手

 

 

4.具体怎么读出JOSN信息对象的键值,有以下两种思路

  • 阅读《cJSON使用以及在stm32中的应用》,使用传统的cJSON代码,解出对象的键值。
  • 利用struct2json库,通过接收josn信息,解出/组合成一个完成结构体,再从结构体一级级读取数值或字符串等等。

 

0积分下载

1.库文件,解压,放入自己工程,添加/.c/.h链接、路径即可使用。

https://download.csdn.net/download/human_cfr/88562288

cJSON使用以及在stm32中的应用

来自 <【C】cJSON使用以及在stm32中的应用-CSDN博客>

cJSON_github源码

来自 <GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C>

JSON格式详解

来自 <前端学习——JSON格式详解_前端json格式-CSDN博客>  

cJSON学习笔记(解析JSON数据包/组装JSON数据包_最基本的用法)

来自 <cJSON学习笔记_【cjson】cjson学习笔记-CSDN博客>

来自 <https://www.cnblogs.com/chineseboy/p/3959852.html>

【开源代码阅读系列】之 cJSON

来自 <【精选】【开源代码阅读系列】之 cJSON_cjson_inithooks_daydayup_666的博客-CSDN博客>

基于STM32FreeRTOS下使用cJSON库的坑

来自 <基于STM32的FreeRTOS下使用cJSON库的坑_cjson_malloc返回空指针-CSDN博客>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1)JSON字符串还原为结构体; 2)访问结构体的字段值; uses SynCommons; const // JSON字符串 JSON1 = '{' + #13#10 + '"glossary": {' + #13#10 + '"title": "中国",' + #13#10 + ' "GlossDiv": {' + #13#10 + '"title": "湖南省",' + #13#10 + ' "GlossList": {' + #13#10 + '"GlossEntry": {' + #13#10 + '"ID": "湘乡市",' + #13#10 + ' "SortAs": "SGML",' + #13#10 + ' "GlossTerm": "Standard Generalized Markup Language",' + #13#10 + ' "Acronym": "SGML",' + #13#10 + ' "Abbrev": "ISO 8879:1986",' + #13#10 + ' "GlossDef": {' + #13#10 + '"para": "A meta-markup language, used to create markup languages such as DocBook.",' + #13#10 + ' "GlossSeeAlso": ["咏南中间件", "XML"]' + #13#10 + '},' + #13#10 + ' "GlossSee": "markup"' + #13#10 + '}' + #13#10 + '}' + #13#10 + '}' + #13#10 + '}' + #13#10 + '}'; type // 记录 TGlossary = record glossary: record title: string; GlossDiv: record title: string; GlossList: record GlossEntry: record ID, SortAs, GlossTerm, Acronym, Abbrev: string; GlossDef: record para: string; GlossSeeAlso: array of string; end; GlossSee: string; end; end; end; end; end; procedure TForm1.Button1Click(Sender: TObject); var gloss: TGlossary; json: RawUTF8; begin json := JSON1; RecordLoadJSON(gloss, @json[1], TypeInfo(TGlossary)); Memo1.Clear; Memo1.Lines.Add(gloss.glossary.title); // 中国 Memo1.Lines.Add(gloss.glossary.GlossDiv.title); // 湖南省 Memo1.Lines.Add(gloss.glossary.GlossDiv.GlossList.GlossEntry.ID); // 湘乡市 Memo1.Lines.Add(gloss.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso[0]); // 咏南中间件 end;
C语言结构体转换为JSON可以通过以下步骤实现: 1. 首先,确保你的C代码中包含了JSON库的头文件。例如,可以使用Jansson库或 cJSON库来处理JSON数据。 2. 创建一个空的JSON对象,用于存储结构体的值。 3. 遍历结构体的每个成员,将其转换为对应的JSON键值对。 4. 使用JSON库提供的函数,将每个成员的值添加到JSON对象中。 5. 最后,将JSON对象转换为字符串表示形式,以便进行传输或存储。 以下是一个示例代码,使用Jansson库将C语言结构体转换为JSON: ```c #include <jansson.h> typedef struct { int id; char name[50]; float price; } Product; int main() { // 创建一个Product结构体对象 Product product = { 1, "Example Product", 9.99 }; // 创建一个空的JSON对象 json_t *json = json_object(); // 将结构体成员添加到JSON对象中 json_object_set_new(json, "id", json_integer(product.id)); json_object_set_new(json, "name", json_string(product.name)); json_object_set_new(json, "price", json_real(product.price)); // 将JSON对象转换为字符串表示形式 char *json_str = json_dumps(json, JSON_INDENT(4)); printf("%s\n", json_str); // 释放内存 free(json_str); json_decref(json); return 0; } ``` 此示例中,结构体`Product`包含了一个整型的`id`,一个字符数组的`name`,以及一个浮点型的`price`。首先,我们创建了一个空的JSON对象`json`。然后,使用`json_object_set_new`函数将结构体成员添加到JSON对象中。最后,使用`json_dumps`函数将JSON对象转换为字符串表示形式。输出结果如下: ```json { "id": 1, "name": "Example Product", "price": 9.990000 } ``` 你可以根据自己的需求使用不同的JSON库来实现结构体JSON的转换。请注意,使用不同的库可能会有不同的API和用法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值