环境:
CST 2024 aarch64 aarch64 aarch64 GNU/Linux
头文件:
#include <json-c/json.h>
编译选项:
gcc xxx.c -o xxx -Wall -g -O0 -std=gnu99 -ljson-c
1. 对象创建函数
| 函数签名 |
说明 |
json_object* json_object_new_object() |
创建空 JSON 对象 |
json_object* json_object_new_array() |
创建空 JSON 数组 |
json_object* json_object_new_string(const char *s) |
创建字符串对象 |
json_object* json_object_new_int(int i) |
创建整数对象 |
json_object* json_object_new_int64(int64_t i) |
创建 64 位整数对象 |
json_object* json_object_new_double(double d) |
创建双精度浮点数对象 |
json_object* json_object_new_boolean(boolean b) |
创建布尔对象(b=1 为 true,b=0 为 false) |
json_object* json_object_new_null() |
创建 null 对象 |
2. JSON 解析函数
| 函数签名 |
说明 |
json_object* json_tokener_parse(const char *str) |
解析 JSON 字符串(返回对象指针) |
json_object* json_tokener_parse_verbose(const char *str, int *error) |
解析 JSON 并返回错误码 |
json_object* json_object_from_file(const char *filename) |
从文件读取并解析 JSON |
3. 对象操作函数
对象(Object)操作
| 函数签名 |
说明 |
void json_object_object_add(json_object *obj, const char *key, json_object *value) |
添加键值对(存在则替换) |
json_object* json_object_object_get(json_object *obj, const char *key) |
获取键对应的值对象 |
int json_object_object_get_ex(json_object *obj, const char *key, json_object **value) |
安全获取值对象(返回是否成功) |
void json_object_object_del(json_object *obj, const char *key) |
删除键值对(释放值对象所有权) |
数组(Array)操作
| 函数签名 |
说明 |
int json_object_array_add(json_object *array, json_object *val) |
向数组末尾添加元素 |
json_object* json_object_array_get_idx(json_object *array, int idx) |
获取数组指定索引的元素 |
int json_object_array_put_idx(json_object *array, int idx, json_object *val) |
替换/插入数组元素 |
int json_object_array_length(json_object *array) |
获取数组长度 |
4. 数据提取函数
| 函数签名 |
说明 |
const char* json_object_get_string(json_object *obj) |
获取字符串值(自动转换) |
int json_object_get_int(json_object *obj) |
获取整数值(自动转换) |
int64_t json_object_get_int64(json_object *obj) |
获取 64 位整数值 |
double json_object_get_double(json_object *obj) |
获取双精度浮点数 |
int json_object_get_boolean(json_object *obj) |
获取布尔值(返回 1/0) |
5. 类型检查函数
| 函数签名 |
说明 |
enum json_type json_object_get_type(json_object *obj) |
返回对象类型(如 json_type_object) |
int json_object_is_type(json_object *obj, enum json_type type) |
检查对象是否为指定类型 |
6. 序列化函数
| 函数签名 |
说明 |
const char* json_object_to_json_string(json_object *obj) |
转换为 JSON 字符串(无格式) |
const char* json_object_to_json_string_ext(json_object *obj, int flags) |
带格式控制(如 JSON_C_TO_STRING_PRETTY 美化输出) |
int json_object_to_file(const char *filename, json_object *obj) |
将 JSON 写入文件 |
7. 内存管理函数
| 函数签名 |
说明 |
int json_object_put(json_object *obj) |
减少引用计数(计数为 0 时释放对象) |
json_object* json_object_get(json_object *obj) |
增加引用计数(防止提前释放) |
8. 迭代器与工具
| 函数签名 |
说明 |
json_object_object_foreach(obj, key, val) |
宏:遍历对象的所有键值对 |
int json_object_array_sort(json_object *jarray, int(*sort_fn)(const void*, const void*)) |
对数组排序 |
json_object* json_object_deep_copy(json_object *obj) |
深拷贝 JSON 对象 |
内存空间问题
json 对象在创建时会有一个引用计数,可以使用 json_object_put 来将其引用计数减一,如果其引用计数为零,其空间就会自动释放。我使用 valgrind --leak-check=full ./xxx 对所有常用api的内存问题进行测试。以下“释放”指的是调用 json_object_put 将对象的引用计数减一。
1、json_object_new_object()
json_object_new_object 生成的对象必须通过 json_object_put 释放,不然就会内存泄漏。一般情况下,所有的创建类函数都需要手动释放。
2、json_object_get_string(obj)
json_object_get_string 会获取 json 对象中的值的指针,无需手动释放内存。
3、多个父对象引用同一个子对象
1
2
3
4
5
6
7
| json_object_object_get_ex(parent_obj1, "data", &son_obj);
json_object_object_add(parent_obj2, "data", son_obj);
// 这种情况需要手动增加引用计数如下,如果不手动增加程序会正常运行,但是valgrind报错
json_object_get(son_obj);
json_object_put(parent_obj1);
json_object_put(parent_obj2);
|
4、json_object_object_get_ex(parent_obj, "data", &son_obj)
son_obj 无需手动释放,在释放 parent_obj 时,son_obj 会自动释放。
5、str = (char *)json_object_to_json_string(obj)
str 无需手动释放,只需要释放 obj
6、json_object_object_add(parent_obj, "data", son_obj)
son_obj 无需手动释放,在释放 parent_obj 时,son_obj 会自动释放。