<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 發(fā)現了一個(gè)很棒的開(kāi)源項目CSON

發(fā)現了一個(gè)很棒的開(kāi)源項目CSON

發(fā)布人:xiaomaidashu 時(shí)間:2023-12-01 來(lái)源:工程師 發(fā)布文章
前言

json是目前最為流行的文本數據傳輸格式,特別是在網(wǎng)絡(luò )通信上廣泛應用,隨著(zhù)物聯(lián)網(wǎng)的興起,在嵌入式設備上,也需要開(kāi)始使用json進(jìn)行數據傳輸,那么,如何快速簡(jiǎn)潔地用C語(yǔ)言進(jìn)行json的序列化和反序列化呢

當前,應用最廣泛的C語(yǔ)言json解析庫當屬cJSON,但是,使用cJSON讀json進(jìn)行序列化和反序列化,需要根據key一個(gè)一個(gè)進(jìn)行處理,會(huì )導致代碼冗余,邏輯性不強,哪有沒(méi)有更好的方法呢

思路

在A(yíng)ndroid平臺,一般會(huì )使用gson等工具解析json,這些工具將json直接映射成對象,在C語(yǔ)言上使用對象的概念,我們需要借助結構體,然而,最大的問(wèn)題在于,C語(yǔ)言沒(méi)有高級語(yǔ)言具有的反射機制,直接從json映射到結構體對象幾乎是不可能的

怎么解決呢,既然C語(yǔ)言沒(méi)有反射機制,那么我們可以自己定義一套類(lèi)似于反射的機制,這里我將其稱(chēng)之為結構體數據模型,在數據模型中,我們需要準確地描述結構體的特征,包括結構體各成員的名稱(chēng),類(lèi)型,在結構體中的偏移,有了這些,我們可以在解析josn的時(shí)候,將解析得到的數據直接寫(xiě)入到對應的內存里面去,或者是在序列化的時(shí)候,直接從對應的內存中讀取數據,進(jìn)行處理

實(shí)現

CSON正是采用上面說(shuō)到的思路,使用數據模型對結構體進(jìn)行描述,然后基于cJSON,根據數據模型進(jìn)行解析,將解析得到的數據直接寫(xiě)入到對應的內存區域,從而實(shí)現從json到結構體對象的映射

CSON最基本的數據模型定義如下:

typedef struct cson_model
{
    CsonType type;                      /**< 數據類(lèi)型 */
    char *key;                          /**< 元素鍵值 */
    short offset;                       /**< 元素偏移 */
} CsonModel;

通過(guò)type描述結構體成員的數據類(lèi)型,key描述該成員在json中對應的字段,offset描述該結構體成員在結構體中的偏移,CSON在解析json的時(shí)候,根據type調用相應的cJSON API并傳遞key作為參數,得到解析出的數據,然后根據offset將數據寫(xiě)入到對應的內存空間

比如說(shuō)這樣一個(gè)結構體:

struct project
{
    int id;
    char *name;
}

該結構體包含兩個(gè)成員,對于成員id,我們使用數據模型對其進(jìn)行描述{.type=CSON_TYPE_CHAR, key="id", offset=0},對于結構體的每個(gè)成員,都進(jìn)行數據模型的定義,就可以得到一個(gè)完整的結構體數據模型,CSON會(huì )根據這個(gè)模型,進(jìn)行解析

因為是通過(guò)直接寫(xiě)內存的方式,所以在寫(xiě)不同類(lèi)型的量到內存中時(shí),會(huì )多次用到強制轉型,導致CSON中賦值的代碼都類(lèi)似于*(int *)((int)obj + model[i].offset) = (int)csonDecodeNumber(json, model[i].key);

當然,上面說(shuō)到的數據模型,只適用于基本數據類(lèi)型的數據,對于子結構體,鏈表,數組等,需要對數據模型的定義進(jìn)行擴充,有興趣的朋友可以直接閱讀CSON源碼

CSON使用實(shí)例聲明結構體
/** 項目結構體 */
struct project
{
    int id;
    char *name;
};

/** 倉庫結構體 */
struct hub
{
    int id;
    char *user;
    struct project *cson;
};
定義數據模型

對每一個(gè)需要使用cson的結構體,都需要定義相對應的數據模型

/** 項目結構體數據模型 */
CsonModel projectModel[] =
{
    CSON_MODEL_OBJ(struct project),
    CSON_MODEL_INT(struct project, id),
    CSON_MODEL_STRING(struct project, name),
};

/** 倉庫結構體數據模型 */
CsonModel hubModel[] =
{
    CSON_MODEL_OBJ(struct hub),
    CSON_MODEL_INT(struct hub, id),
    CSON_MODEL_STRING(struct hub, user),
    CSON_MODEL_STRUCT(struct hub, cson, projectModel, sizeof(projectModel)/sizeof(CsonModel))
};
使用CSON解析

只需要定義好數據模型,就可以使用CSON讀json進(jìn)行序列化和反序列化

void csonDemo(void)
{
    char *jsonDemo = "{"id": 1, "user": "Letter", "cson": {"id": 2, "name": "cson"}}";

    /** 解析json */
    struct hub *pHub = csonDecode(jsonDemo, hubModel, sizeof(hubModel)/sizeof(CsonModel));
    printf("hub: id: %d, user: %s, project id: %d, project name: %srn",
        pHub->id, pHub->user, pHub->cson->id, pHub->cson->name);

    /** 序列化對象 */
    char *formatJson = csonEncodeFormatted(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));
    printf("format json: %srn", formatJson);

    /** 釋放結構體對象 */
    csonFree(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));

    /** 釋放序列化生成的json字符串 */
    csonFreeJson(formatJson);
}

運行結果:

hub: id: 1, user: Letter, project id: 2, project name: cson
format json: {
        "id":   1,
        "user": "Letter",
        "cson": {
                "id":   2,
                "name": "cson"
        }
}

可以看到,無(wú)論是解析json,還是序列化結構體到j(luò )son,在使用CSON的情況下,都只需要一行代碼就可以解決,同樣的操作,在使用原生cJSON的情況下,你可能需要多次判斷,解析元素

項目地址

CSON項目已經(jīng)發(fā)布到Githubhttps://github.com/NevermindZZT/cson


*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: CSON

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>