json庫函式入門例子,詳解。--C語言
// 還是得多動手總結啊,不足之處,還望提醒。編譯的時候,記得加上 -ljson 庫
#include<stdio.h> #include "json/json.h" void make_a_common_json_string(); int main() { struct json_object *my_obj; //json格式的字串,\"string\".(特殊字元加轉義符) char *str="{\"abc\": 123, \"wds\": 12.3, \"qwe\": \"ddd\", \"bool0\": false, \"bool1\": true, \"arr\": [12, 3, 0, 5, null]}"; //將符合json格式的字串構造為一個json物件 my_obj = json_tokener_parse(str); printf("1-tokener parse: %s\n", json_object_to_json_string(my_obj)); // 在物件裡用key值去找,然後刪除它的key:value. json_object_object_del(my_obj, "abc"); printf("2-tokener parse: %s\n", json_object_to_json_string(my_obj)); struct json_object *ret_obj; // 在物件裡用key值去找,獲取它的value值 ret_obj = json_object_object_get(my_obj, "wds"); printf("obj_get-wds:%s\n", json_object_to_json_string(ret_obj)); // 在json_object_object_get 引用一次。 // 將jso物件的引用計數減1,子物件引用計數為0時釋放所佔用記憶體。 json_object_put(ret_obj); // 獲取不同的json資料型別,int.double.string.array.object. struct json_object *val = json_object_new_int(18542); // 將key:value加入到物件my_obj中. json_object_object_add(my_obj, "wds", val); printf("3-object add: %s\n", json_object_to_json_string(my_obj)); // 看function詳解1 json_object_put(val); printf("get string:%s\n", json_object_get_string(my_obj)); printf("get lh:%d\n", json_object_get_object(my_obj)); printf("get int:%d\n", json_object_get_int(my_obj)); make_a_common_json_string(); // 看function詳解1 json_object_put(my_obj); return 0; } // 這個介面,包含了很多資料型別(array, int, string, object)。組成json包,socket傳輸,為上層提供資料,便於展示。 void make_a_common_json_string() { printf("####################################\n"); int i=0; struct json_object *obj_all = json_object_new_object(); struct json_object *obj_info = json_object_new_object(); struct json_object *obj_work = json_object_new_object(); struct json_object *obj_life = json_object_new_object(); struct json_object *arr_month_grade = json_object_new_array(); for(i=1; i<13; i++){ struct json_object *obj_int = json_object_new_int(i); json_object_array_add(arr_month_grade, obj_int); } //const char *str = "{\"職位\": \"programmer\", \"部門\": \"研發\", \"addres\": \"BJ.3\"}"; //json_object *obj_str = json_tokener_parse(str); json_object_object_add(obj_work, "position", json_object_new_string("programmer")); json_object_object_add(obj_work, "department", json_object_new_string("make code")); json_object_object_add(obj_work, "address", json_object_new_string("BJ.3.103")); json_object_object_add(obj_work, "mounth_grade", arr_month_grade); json_object_object_add(obj_info, "Work", obj_work); json_object_object_add(obj_life, "Name", json_object_new_string("DS.wen")); json_object_object_add(obj_life, "Age", json_object_new_int(24.34)); json_object_object_add(obj_life, "M-O", json_object_new_string("Male")); json_object_object_add(obj_info, "Life", obj_life); json_object_object_add(obj_all,"W.DS_Info", obj_info); printf("all_string:%s\n", json_object_to_json_string(obj_all)); json_object_put(obj_all); return ; }
/*************************************列印結果********************************************/ 1-tokener parse: { "abc": 123, "wds": 12.300000, "qwe": "ddd", "bool0": false, "bool1": true, "arr": [ 12, 3, 0, 5, null ] } 2-tokener parse: { "wds": 12.300000, "qwe": "ddd", "bool0": false, "bool1": true, "arr": [ 12, 3, 0, 5, null ] } obj_get-wds:12.300000 3-object add: { "wds": 18542, "qwe": "ddd", "bool0": false, "bool1": true, "arr": [ 12, 3, 0, 5, null ] } get string:{ "wds": 18542, "qwe": "ddd", "bool0": false, "bool1": true, "arr": [ 12, 3, 0, 5, null ] } get lh:26383664 get int:0 #################################### all_string:{ "W.DS_Info": { "Work": { "position": "programmer", "department": "make code", "address": "BJ.3.103", "mounth_grade": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ] }, "Life": { "Name": "DS.wen", "Age": 24, "M-O": "Male" } } } /********************************************************************************************************************/
/-----------------------------function--------------------------------------/
1. struct json_object * * json_object_get(struct json_object * this)
說明:
增加物件引用計數。使用c庫最關心的是記憶體誰來分配, 誰來釋放. jsonc的記憶體管理方式, 是基於引用計數的記憶體樹(鏈), 如果把一個struct json_object 物件a, add到另一個物件b上, 就不用顯式的釋放(json_object_put) a了, 相當於把a掛到了b的物件樹上, 釋放b的時候, 就會釋放a. 當a即add到b上, 又add到物件c上時會導致a被釋放兩次(double free), 這時可以增加a的引用計數(呼叫函式json_object_get(a)), 這時如果先釋放b,
後釋放c, 當釋放b時, 並不會真正的釋放a, 而是減少a的引用計數為1, 然後釋放c時, 才真正釋放a.
引數:
this – json物件
Void json_object_put(struct json_object * this)
說明:
減少物件引用次數一次,當減少到0就釋放(free)資源
引數:
this – json物件
注:如果對json物件顯式呼叫了json_object_get,之後必須成對呼叫json_object_put,否則將導致該json物件所佔用記憶體洩漏。
2. json_object_new_XXX系列函式 struct json_object* json_object_new_object(void);
struct json_object* json_object_new_int(int i);
struct json_object* json_object_new_double(double d);
struct json_object* json_object_new_array(void);
struct json_object* json_object_new_string(const char *s);
struct json_object* json_object_new_string_len(const char *s, int len);
json_object_new_XXX系列函式用來建立XXX型別的json物件,建立的json物件預設引用計數為1,因此在該物件使用完後也需要呼叫一次json_object_put來把引用計數置0,從而釋放記憶體。
3. json_tokener_parse函式 struct json_object* json_tokener_parse(const char *str);
json_tokener_parse將符合json格式的字串構造為一個json物件,構造的json物件預設引用計數為1,同樣需要在使用完後對該物件呼叫一次json_object_put。
4. is_error巨集
is_error(jso)
如果傳入的字串是非法的json格式,錯誤判斷應該使用is_error巨集,而非 if(NULL != jso),CGI中目前有很多這種錯誤用法(雖然好像沒引發什麼問題)
5. json_object_object_XXX函式
void json_object_object_del(struct json_object* jso, const char *key);
從jso物件中刪除鍵值為key的子物件,並釋放該子物件及鍵值所佔的記憶體(注:可能有文件說json_object_object_del只是刪除而不釋放記憶體,但實際上這是錯誤的)。
struct json_object* json_object_object_get(struct json_object* jso, const char *key); 從jso中獲取鍵值為key的子物件。錯誤判斷同樣應該用is_error(jso)巨集。
void json_object_object_add(struct json_object* jso, const char *key, struct json_object *val); 更新鍵值為key的子項的值。整個過程實際上是這樣的:先從jso中刪除並釋放鍵值key及其值的記憶體,然後重新分配記憶體新增鍵值和新的值,所以json_object_object_add是包含json_object_object_del操作的。
6. json_object_get_XXX系列函式 struct lh_table* json_object_get_object(struct json_object *jso);
const char* json_object_get_string(struct json_object *jso);
int json_object_get_int(struct json_object *jso);
double json_object_get_double(struct json_object *jso); 這類函式只是獲取jso物件的實際資料內容,不更新引用計數,也不分配記憶體。
7. json_object_array_XXX系列函式
struct json_object* json_object_array_get_sub_array(struct json_object *jso, int start_idx, int number);
這個函式用來從一個json陣列物件中取陣列序號start_idx開始的、總共number長度的子陣列物件。分頁顯示功能常用到。注:返回的子陣列是有重新分配記憶體的,所以同樣要對返回的json_object*做一次json_object_put操作來釋放記憶體。
int json_object_array_add(struct json_object *jso,struct json_object *val); 向陣列中新增一個值。
int json_object_array_length(struct json_object *jso); 獲取陣列長度。
int json_object_array_put_idx(struct json_object *jso, int idx, struct json_object *val); 更新陣列中序號為idx那一項的值,老的值同樣會先被釋放。
struct json_object* json_object_array_get_idx(struct json_object *jso, int idx); 獲取陣列中序號為idx那一項的json物件,不更新引用計數,也不分配記憶體。
struct json_object* json_object_array_sort(struct json_object *jso, const char *keyname, int sord ); 根據鍵值為keyname的項的值進行升序或降序排序,只是改變陣列成員的順序,不更新引用計數,也不分配記憶體。