介绍
Jansson是一个对json格式进行编码,解码,操作的c语言库,有以下特点
- 简单的api设计
- 文档详尽
- 无其他依赖库
- 完全支持UTF-8
- 大量的测试用例
Jansson是MIT license源码发布方式
Jansson支持多个平台,包括Unix以及windows
编译安装
解压并编译
tar -xvf jansson-2.4.tar.gz
./configure
make
make check
make install
简单使用
只需要包含一个头文件
#include <jansson.h>
直接连接库方式编译
gcc -o prog prog.c -ljansson
或者利用pkg-config
gcc -o prog prog.c `pkg-config --cflags --libs jasson`
类型以及接口介绍
类型
Jasson主要使用的类型为
json_t
enum json_type
JSON_OBJECT
JSON_ARRAY
JSON_STRING
JSON_INTEGER
JSON_REAL
JSON_TRUE
JSON_FALSE
JSON_NULL
int json_typeof(const json_t *json)
json_is_object(const json_t *json)
json_is_array(const json_t *json)
json_is_string(const json_t *json)
json_is_integer(const json_t *json)
json_is_real(const json_t *json)
json_is_true(const json_t *json)
json_is_false(const json_t *json)
json_is_null(const json_t *json)
引用计数
Jasson利用引用计数管理内存,下面两个接口进行引用计数的增加和减少
json_t *json_incref(json_t *json)
void json_decref(json_t *json)
一般的操作是不会引起引用计数的变化的,需要人工进行增减,但是对于以_new
或者 _new_
结束的可以自动对引用计数进行增减。
其他接口信息参见API Reference
例子
根据jansson-example摘抄如下
jansson.c
#include <stdio.h>
#include <string.h>
#include <jansson.h>
int main(void) {
char* s = NULL;
json_t *root = json_object();
json_t *json_arr = json_array();
json_object_set_new( root, "destID", json_integer( 1 ) );
json_object_set_new( root, "command", json_string("enable") );
json_object_set_new( root, "respond", json_integer( 0 ));
json_object_set_new( root, "data", json_arr );
json_array_append( json_arr, json_integer(11) );
json_array_append( json_arr, json_integer(12) );
json_array_append( json_arr, json_integer(14) );
json_array_append( json_arr, json_integer(9) );
s = json_dumps(root, 0);
puts(s);
json_decref(root);
return 0;
}
使用gcc -g -o jansson jansson.c -ljansson,然后运行结果:
{"destID": 1, "command": "enable", "respond": 0, "data": [11, 12, 14, 9]}
如果你看到这里觉得结果输出没问题,按照上面的使用,可就捅了大篓子了,特别是针对频繁操作json的情况,看下执行valgrind后的结果:
[root jansson]#valgrind --leak-check=full ./jansson
==16417== Memcheck, a memory error detector
==16417== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16417== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==16417== Command: ./jansson
==16417==
{"destID": 1, "command": "enable", "respond": 0, "data": [11, 12, 14, 9]}
==16417==
==16417== HEAP SUMMARY:
==16417== in use at exit: 170 bytes in 5 blocks
==16417== total heap usage: 21 allocs, 16 frees, 1,037 bytes allocated
==16417==
==16417== 24 bytes in 1 blocks are definitely lost in loss record 1 of 5
==16417== at 0x4C29E63: malloc (vg_replace_malloc.c:309)
==16417== by 0x4E3F77D: json_integer (in /usr/lib64/libjansson.so.4.10.0)
==16417== by 0x4008FE: main (jansson.c:14)
==16417==
==16417== 24 bytes in 1 blocks are definitely lost in loss record 2 of 5
==16417== at 0x4C29E63: malloc (vg_replace_malloc.c:309)
==16417== by 0x4E3F77D: json_integer (in /usr/lib64/libjansson.so.4.10.0)
==16417== by 0x40091A: main (jansson.c:15)
==16417==
==16417== 24 bytes in 1 blocks are definitely lost in loss record 3 of 5
==16417== at 0x4C29E63: malloc (vg_replace_malloc.c:309)
==16417== by 0x4E3F77D: json_integer (in /usr/lib64/libjansson.so.4.10.0)
==16417== by 0x400936: main (jansson.c:16)
==16417==
==16417== 24 bytes in 1 blocks are definitely lost in loss record 4 of 5
==16417== at 0x4C29E63: malloc (vg_replace_malloc.c:309)
==16417== by 0x4E3F77D: json_integer (in /usr/lib64/libjansson.so.4.10.0)
==16417== by 0x400952: main (jansson.c:17)
==16417==
==16417== 74 bytes in 1 blocks are definitely lost in loss record 5 of 5
==16417== at 0x4C29E63: malloc (vg_replace_malloc.c:309)
==16417== by 0x4E3CC44: ??? (in /usr/lib64/libjansson.so.4.10.0)
==16417== by 0x4E3A107: json_dumps (in /usr/lib64/libjansson.so.4.10.0)
==16417== by 0x400975: main (jansson.c:18)
==16417==
==16417== LEAK SUMMARY:
==16417== definitely lost: 170 bytes in 5 blocks
==16417== indirectly lost: 0 bytes in 0 blocks
==16417== possibly lost: 0 bytes in 0 blocks
==16417== still reachable: 0 bytes in 0 blocks
==16417== suppressed: 0 bytes in 0 blocks
==16417==
==16417== For lists of detected and suppressed errors, rerun with: -s
==16417== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
存在内存泄露,正确的代码如下:
#include <stdio.h>
#include <string.h>
#include <jansson.h>
int main(void) {
char* s = NULL;
json_t *root = json_object();
json_t *json_arr = json_array();
json_object_set_new( root, "destID", json_integer( 1 ) );
json_object_set_new( root, "command", json_string("enable") );
json_object_set_new( root, "respond", json_integer( 0 ));
json_object_set_new( root, "data", json_arr );
json_array_append_new( json_arr, json_integer(11) );
json_array_append_new( json_arr, json_integer(12) );
json_array_append_new( json_arr, json_integer(14) );
json_array_append_new( json_arr, json_integer(9) );
s = json_dumps(root, 0);
puts(s);
json_decref(root);
if(s)
{
free(s);
}
return 0;
}
解释如下:json_dumps函数里存在malloc,因此需要通过free释放内存。
json_array_append与json_array_append_new的区别是:
int json_array_append(json_t *array, json_t *value)
{
return json_array_append_new(array, json_incref(value));
}
json_array_append对第二个参数传进来的json_t增加了引用,因此原结构没有释放。
修改后的代码通过valgrind执行结果:
[root jansson]#valgrind --leak-check=full ./jansson
==14943== Memcheck, a memory error detector
==14943== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14943== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==14943== Command: ./jansson
==14943==
{"destID": 1, "command": "enable", "respond": 0, "data": [11, 12, 14, 9]}
==14943==
==14943== HEAP SUMMARY:
==14943== in use at exit: 0 bytes in 0 blocks
==14943== total heap usage: 21 allocs, 21 frees, 1,037 bytes allocated
==14943==
==14943== All heap blocks were freed -- no leaks are possible
==14943==
==14943== For lists of detected and suppressed errors, rerun with: -s
==14943== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)