在这篇文章中博主简单介绍了如何把cJSON移植到STM32上,实际上,keil环境下已经有官方的JSON库了——Jansson。下面是讲解如何导入和使用Jansson。
下载地址:http://www2.keil.com/mdk5/partnerpacks/
下载Keil.Jansson.1.0.0.pack后双击安装,打开keil工程,点击下图的图标配置Json库到工程里。
接下来按图点击,最后点击OK。
最后工程目录下面就有会Jansson的lib文件了。
之后可以使用下面的代码测试打包json数据。
#include
//jansson Test
void jansson_pack_test(void)
{
json_t *root;
char *out;
/* Build an empty JSON object */
root = json_pack("{}");
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
/* Build the JSON object {"foo": 42, "bar": 7} */
root = json_pack("{sisi}", "foo", 42, "bar", 7);
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
/* Like above, ':', ',' and whitespace are ignored */
root = json_pack("{s:i, s:i}", "foo", 42, "bar", 7);
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
/* Build the JSON array [[1, 2], {"cool": true}] */
root = json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
/* Build a string from a non-null terminated buffer */
char buffer[4] = {'t', 'e', 's', 't'};
root = json_pack("[s#]", buffer, 4);
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
/* Concatenate strings together to build the JSON string "foobarbaz" */
root = json_pack("[s++]", "foo", "bar", "baz");
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
}
打印
out:{}
out:{
"foo": 42,
"bar": 7
}
out:{
"foo": 42,
"bar": 7
}
out:[[1, 2], {"cool": true}]
out:["test"]
out:["foobarbaz"]
在评论区有位朋友问为什么用UTF-8编码打包的Json打印出来是乱码。经过博主几天的查资料,现在问题是这样的:实际上用Jansson编码UTF-8的中文是没有问题的,有问题的是串口的打印问题。
这是我测试串口打印中文,首先说明几点,我的文件保存格式是keil默认的格式,也就是ANSI,大家打开记事本然后点击另存为,在保存路径下面可以选择其编码格式:
把串口打印出来的数据拷贝到Notepad++,拷贝前先新建一个文档并以ANSI编码:
拷贝过去后没有出现任何乱码,可见串口打印显示的是ANSI编码字符。
在Notepad++的菜单栏,选择「格式」,「以UTF-8编码」,有无BOM都行,然后看到后面的乱码正常显示中文了:
而且,如果使用非UTF-8字符打包Json,Jansson是会返回「Invalid UTF-8 string」错误信息的,当然前提是使用json_pack_ex
函数。
/* 文件以ANSI格式存储,keil MDK默认的格式 */
char *zhongwen = "中文";
root = json_pack_ex(&e, JSON_ENCODE_ANY, "[s]", zhongwen);
printf("e:%s\r\n", e.text);
下面放上本小节测试代码。
/* 文件以ANSI格式存储,keil MDK默认的格式 */
char *zhongwen = "中文";
char *zhongwen_utf8 = "\xE4\xB8\xAD\xE6\x96\x87";
printf("zhongwen:%s\r\n", zhongwen);
printf("zhongwen_utf8:%s\r\n", zhongwen_utf8);
json_error_t e;
root = json_pack_ex(&e, JSON_ENCODE_ANY, "[s]", zhongwen);
printf("e:%s\r\n", e.text);
root = json_pack_ex(&e, JSON_ENCODE_ANY, "[s]", zhongwen_utf8);
printf("e:%s\r\n", e.text);
out = json_dumps(root, JSON_ENCODE_ANY);
printf("out:%s\r\n", out);
free(root);
free(out);
2018年6月4日更新:
实际上代码末尾使用free()
来释放内存不够规范,可能会造成内存泄漏,应该使用json_object_clear()
接口清理(待验证)。具体方法最好查看相关文档:
json_dumps
:http://jansson.readthedocs.io/en/latest/apiref.html#c.json_dumpsjson_object_clear
:http://jansson.readthedocs.io/en/latest/apiref.html#c.json_object_clear(相关内容:评论区4楼)
2019年7月29日更新:
感谢 #8楼 回复。关于json数据释放问题请不要使用free()
释放。具体内容请看评论区 #8楼 。
json_delete(root);//不要用free,用free()会导致Heap溢出
由于很久没玩STM32了,所以这里就只简单提醒。任何时候请一定要仔细阅读官方文档。