json是目前最為流行的文本數(shù)據(jù)傳輸格式,特別是在網(wǎng)絡通信上廣泛應用,隨著物聯(lián)網(wǎng)的興起,在嵌入式設備上,也需要開始使用json進行數(shù)據(jù)傳輸,那么,如何快速簡潔地用C語言進行json的序列化和反序列化呢?
當前,應用最廣泛的C語言json解析庫當屬cJSON,但是,使用cJSON讀json進行序列化和反序列化,需要根據(jù)key一個一個進行處理,會導致代碼冗余,邏輯性不強,哪有沒有更好的方法呢?
思路
在Android平臺,一般會使用gson等工具解析json,這些工具將json直接映射成對象,在C語言上使用對象的概念,我們需要借助結構體,然而,最大的問題在于,C語言沒有高級語言具有的反射機制,直接從json映射到結構體對象幾乎是不可能的。
怎么解決呢,既然C語言沒有反射機制,那么我們可以自己定義一套類似于反射的機制,這里我將其稱之為結構體數(shù)據(jù)模型,在數(shù)據(jù)模型中,我們需要準確地描述結構體的特征,包括結構體各成員的名稱,類型,在結構體中的偏移。
有了這些,我們可以在解析josn的時候,將解析得到的數(shù)據(jù)直接寫入到對應的內(nèi)存里面去,或者是在序列化的時候,直接從對應的內(nèi)存中讀取數(shù)據(jù),進行處理。
實現(xiàn)
CSON正是采用上面說到的思路,使用數(shù)據(jù)模型對結構體進行描述,然后基于cJSON,根據(jù)數(shù)據(jù)模型進行解析,將解析得到的數(shù)據(jù)直接寫入到對應的內(nèi)存區(qū)域,從而實現(xiàn)從json到結構體對象的映射。
CSON最基本的數(shù)據(jù)模型定義如下:
typedef struct cson_model
{
CsonType type; /**< 數(shù)據(jù)類型 */
char *key; /**< 元素鍵值 */
short offset; /**< 元素偏移 */
} CsonModel;
通過type描述結構體成員的數(shù)據(jù)類型,key描述該成員在json中對應的字段,offset描述該結構體成員在結構體中的偏移,CSON在解析json的時候,根據(jù)type調(diào)用相應的cJSON API并傳遞key作為參數(shù),得到解析出的數(shù)據(jù),然后根據(jù)offset將數(shù)據(jù)寫入到對應的內(nèi)存空間。
比如說這樣一個結構體:
struct project
{
int id;
char *name;
}
該結構體包含兩個成員,對于成員id,我們使用數(shù)據(jù)模型對其進行描述
{.type=CSON_TYPE_CHAR, key="id", offset=0}
對于結構體的每個成員,都進行數(shù)據(jù)模型的定義,就可以得到一個完整的結構體數(shù)據(jù)模型,CSON會根據(jù)這個模型,進行解析。
因為是通過直接寫內(nèi)存的方式,所以在寫不同類型的量到內(nèi)存中時,會多次用到強制轉(zhuǎn)型,導致CSON中賦值的代碼都類似于:
*(int *)((int)obj + model[i].offset) = (int)csonDecodeNumber(json, model[i].key);
當然,上面說到的數(shù)據(jù)模型,只適用于基本數(shù)據(jù)類型的數(shù)據(jù),對于子結構體,鏈表,數(shù)組等,需要對數(shù)據(jù)模型的定義進行擴充,有興趣的朋友可以直接閱讀CSON源碼。
-
數(shù)據(jù)
+關注
關注
8文章
6762瀏覽量
88622 -
C語言
+關注
關注
180文章
7581瀏覽量
135594 -
模型
+關注
關注
1文章
3063瀏覽量
48576 -
JSON
+關注
關注
0文章
114瀏覽量
6921
發(fā)布評論請先 登錄
相關推薦
評論