前段時間因為工作內容涉及通訊協議中使用json格式作為雙方通訊的基礎協議格式,所以有機會接觸到了jsoncpp這個開源庫。
jsoncpp這個庫很不錯,當你拿到json數據字符串的時候只需要做:
Json::Reader jr; Json::Value jv; if(!jr.parse(json,jv)) { printf("parse err!\n"); return false; }
這樣你即可反序列化出來你想要的數據到jv這個變量里面了,如果你想使用jv獲取到json里面的某個數據的話,只需要:
long long age=jv["age"].asInt64();//獲取{"age":16}的age值
1:性能上效率比較低,因為Json::Value里面應該用了map這樣的方法去查找相對於的字符串去一個一個的查找對象這樣效率會比較低
2:比較容易出錯,比如你的要獲取{“angel”:1} 在代碼中寫成了 jv[“angry”].asInt64(); 這樣編譯器並不會報錯,
3:你還要干很多檢查的事情,如 對方傳過來的 angel 是個字符串,你在asInt64()的時候程序就崩潰了,你必須要檢查過來的數據類型對不對
4:因為你的工程中很多地方都要用到這個數據,你的整個工程都被病毒式的傳染了,到處都是Json::Value
5:還有很多很多問題…
所以要解決以上問題,你必須把json解析到相同的一個結構體中 如:
先定義一下你的通訊協議格式:
{ //先給你的json數據包格式起個名字叫做rpc1 "rpc1" : { "age":16,//年齡 "hp":99,//血 "mp":88//魔法 } }
這樣做既可當初文檔來用了,其中 這個通訊協議的名字叫做rpc1,里面會傳輸 age hp mp這三個數據,他們都是整形,如果不傳輸的話,程序默認他為分別為16 99 88
好了,現在你要寫一段代碼用jsoncpp解析到你的一個有相同結構的結構體(類)里面
//charset: #ifndef test_json_h #define test_json_h #include <vector> #include <string> #include "json.h" ////////////////////////////////////////////////////////////////////////// //先給你的json數據包格式起個名字叫做rpc1 class rpc1 { private: public: rpc1() { age = 16; hp = 99; mp = 88; } void reset() { age = 16; hp = 99; mp = 88; } bool decode(std::string json) { Json::Reader jr; Json::Value jv; if(!jr.parse(json,jv)) { printf("parse err!\n"); return false; } return decode(jv); } bool decode(Json::Value & jv) { if( jv["age"].type()==Json::intValue || jv["age"].type()==Json::uintValue ) age = jv["age"].asInt64(); if( jv["hp"].type()==Json::intValue || jv["hp"].type()==Json::uintValue ) hp = jv["hp"].asInt64(); if( jv["mp"].type()==Json::intValue || jv["mp"].type()==Json::uintValue ) mp = jv["mp"].asInt64(); return true; } std::string encode2string() { return encode().toStyledString(); } Json::Value encode() { Json::Value root; root["age"]=Json::Value(age); root["hp"]=Json::Value(hp); root["mp"]=Json::Value(mp); return root; } long long age; //年齡 long long hp; //血 long long mp; //魔法 } ; ////////////////////////////////////////////////////////////////////////// #endif //test_json_h
好了,你的代碼只是要寫出向上面這樣才能算完整,里面包含初始化默認值,解析json(decode) 或者是生成json(encode)功能,還包含各種數據類型檢查功能以及重置初始值。
使用方法就比較簡單了:
rpc1 r; r.decode(str);//str是你要解析的字符串 long long age=r.age;//獲取age long long hp=r.hp;//獲取hp long long mp=r.mp;//獲取mp string str2=r.encode2string();//生成json字符串
你看這樣用起來十分簡單了? 但是如果你的通訊協議有很多要轉換的json數據,以及每個json里面的數據非常復雜,你要寫的代碼是會非常多的,所以你需要一款工具,幫你自動的從一個json文件(協議格式定義文件)轉換成一個c++代碼文件
這就有了我做的json2jsoncpp
你只需要寫好json文件,這個工具就可以生成一個h文件來了
工具使用比較簡單,就是
json2jsoncpp.exe yourjson [yourh]
這樣就能生成出來你要的h文件了
json的定義格式也很簡單,首先它就是個標准的json格式文件
類似這樣:
{ //如果你需要給你生成的h文件包含一個命名空間,只需要寫入: "namespace":"KAKA", //先給你的json數據包格式起個名字叫做rpc1 "rpc1" : { "age":16,//年齡 "hp":99,//血 "mp":88//魔法 }, //第二個數據格式 "rpc2" : { "box":16 } }
按照這格式你就可以生成你想要的h文件了
類里面包含幾個方法:
decode() //解碼json數據
encode() //編碼成Json::Value變量
encode2string() //編碼成string
reset() //重置變量恢復到默認值
附上 win/mac/linux 的應用下載地址:http://pan.baidu.com/share/link?shareid=308752&uk=3711199009
先寫到這里,下回再說說哦json2jsoncpp的一些高級應用
附:我叫楊卡,目前在廣州一家做視頻監控平台的公司擔任開發工程師/主管,在工作與學習的過程中有一些心得體會在這里與大家分享分享,與大家一起共同學習與進步,歡迎大家多多關注。
我的hotmail.com信箱是:vanishs