JSON構造/解析(by C)---cJSON和json-c


背景

JSON即JavaScript Object Notation,是一種輕量級的數據交換格式。

JSON建構於兩種結構:

  • “名稱/值”對的集合(A collection of name/value pairs)。不同的語言中,它被理解為對象(object),紀錄(record),結構(struct),字典(dictionary),哈希表(hash table),有鍵列表(keyed list),或者關聯數組 (associative array)。
  • 值的有序列表(An ordered list of values)。在大部分語言中,它被理解為數組(array)。

關於JSON庫的性能評測與標准符合程度,可以參照《28 個 C/C++ 開源 JSON 程序庫性能及標准符合程度評測》,另一個英文版更詳細結果在nativejson-benchmark

在閱讀了一系列評測之后,結合需求(ROM盡量小,RAM盡量小,帶處理的數據比較簡單),准備研究一下cJSON和json-c。

JSON官網獲得json-c和cJSON的源碼地址如下:cJSONjson-c

下面就基於這兩份代碼在Ubuntu進行速度和兼容性測試。

測試標的構造對於測試的覆蓋以及測試有效性非常重要,所幸的在AOSP中有一個參考AOSP/external/jsoncpp/test。

cJSON

下載代碼:

git clone https://github.com/arnoldlu/cJSON.git

編譯安裝:

mkdir build
cd build
cmake .. -DENABLE_CJSON_UTILS=Off -DENABLE_CJSON_TEST=On -DCMAKE_INSTALL_PREFIX=/usr (生成bin+lib)
cmake .. -DENABLE_CJSON_UTILS=Off -DENABLE_CJSON_TEST=On -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=Off (生成bin)
make
sudo make install (安裝libcjson.so)

使用實例

參考文檔:《使用 CJSON 在C語言中進行 JSON 的創建和解析的實例講解》、《cJSON學習筆記》。

下面是一個構造JSON數據,然后解析,打印Type-Key-Value的小示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"

void printJson(cJSON *root)
{
    if(!root)
    {
        printf("NULL JSON root.\n");
        return;
    }
   
    printf("Type=0x%02x, %s=%s\n", root->type, root->string, cJSON_Print(root));  cJSON_Print會根據類型打印
}

static char * makeJson(void)
{
    cJSON *pJsonRoot = NULL;
    cJSON *pSubJson = NULL;
    char *p = NULL;

    pJsonRoot = cJSON_CreateObject();
    if(NULL == pJsonRoot)
    {
        printf("%s line=%d NULL\n", __func__, __LINE__);
        return NULL;
    }
    cJSON_AddStringToObject(pJsonRoot, "hello", "hello world");  String類型
    cJSON_AddNumberToObject(pJsonRoot, "number", 10010);  Number類型
    cJSON_AddBoolToObject(pJsonRoot, "bool", 1);  bool類型
    pSubJson = cJSON_CreateObject();  建一個cJSON,用於嵌套數據
    if(NULL == pSubJson)
    {
        printf("%s line=%d NULL\n", __func__, __LINE__);
        cJSON_Delete(pJsonRoot);
        return NULL;
    }
    cJSON_AddStringToObject(pSubJson, "subjsonobj", "a sub json string");  在子cJSON下,增加一個String類型數據
    cJSON_AddItemToObject(pJsonRoot, "subobj", pSubJson);  將子cJSON加入到pJsonRoot

    p = cJSON_Print(pJsonRoot);
    if(NULL == p)
    {
        printf("%s line=%d NULL\n", __func__, __LINE__);
        cJSON_Delete(pJsonRoot);
        return NULL;
    }

    cJSON_Delete(pJsonRoot);

    return p;
}


static void parseJson(char * pMsg)
{
    cJSON *pJson;
    cJSON *pSub;
    cJSON * pSubSub;

    if(NULL == pMsg)
    {
    return;
    }

    pJson = cJSON_Parse(pMsg);
    if(NULL == pJson)                                                                                        
    {
        return ;
    }

    pSub = cJSON_GetObjectItem(pJson, "hello");
    printJson(pSub);

    pSub = cJSON_GetObjectItem(pJson, "number");
    printJson(pSub);

    pSub = cJSON_GetObjectItem(pJson, "bool");
    printJson(pSub);

    pSub = cJSON_GetObjectItem(pJson, "subobj");
    printJson(pSub);

    pSubSub = cJSON_GetObjectItem(pSub, "subjsonobj");
    printJson(pSubSub);

    cJSON_Delete(pJson);
}

int main(void)
{
    char *p;

    /* print the version */
    printf("Version: %s\n", cJSON_Version());  獲取cJSON版本號

    p = makeJson();  構造JSON數據
    if(NULL == p)
    {
        return 0;
    }
    printf("p = \n%s\n\n", p);  打印構造的字符串
    parseJson(p);  解析JSON數據,並打印Type-Key-Value
    free(p);
    return 0;
}

在安裝(sudo make install)cJSON之后,編譯的時候需要跟上libcjson庫文件:

gcc demo.c -o demo -lcjson

執行結果如下:

Version: 1.3.2
p =
{
    "hello":    "hello world",
    "number":    10010,
    "bool":    true,
    "subobj":    {
        "subjsonobj":    "a sub json string"
    }
}

Type=0x10, hello="hello world"
Type=0x08, number=10010
Type=0x02, bool=true
Type=0x40, subobj={
    "subjsonobj":    "a sub json string"
}
Type=0x10, subjsonobj="a sub json string"

json-c

參考文檔:《JSON C庫的使用

下載代碼:

git clone https://github.com/arnoldlu/json-c.git

編譯安裝:

sh autogen.sh
./configure
make
make install


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM