Author:Echo Chen(陳斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:September 28th, 2014
Explain
最近在做游戲接入SDK時用到C++的json庫jsoncpp,jsoncpp 是一款優秀的json庫,但惡心的一點是它采用Assert作為錯誤處理方法,而assert在linux下通過調用 abort 來終止程序運行,對於服務器而言將會收到SIGABRT,崩潰打出core,這對於服務器而言是致命的,下面總結了幾種 Assertion `type_ == nullValue || type_ == object Value' failed的情況。
1: Json::Reader *pJsonParser = new Json::Reader();
2: string strJson = "1111 {}"; //不合法json
3:
4: Json::Value tempVal;
5:
6: if(!pJsonParser->parse(strJson, tempVal))
7: {
8: cout << "parse error" << endl;
9: return -1;
10: }
11: string name = tempVal["name"].asString();
由於Jsoncpp解析非法json時,會自動容錯成字符類型。對字符類型取下標時,會觸發assert終止進程。
解決方法:啟用嚴格模式,讓非法的json解析時直接返回false,不自動容錯。這樣,在調用parse的時候就會返回false。
1: Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
1: Json::Reader *pJsonParser = new Json::Reader();
2: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\',\'sex\':\'男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";
3:
4: Json::Value tempVal;
5:
6: if(!pJsonParser->parse(strJson, tempVal))
7: {
8: return -1;
9: }
10:
11: string friendsName = tempVal["friends"]["name"].asString();
由於friends為數組,直接取name,會Assertion `type_ == nullValue || type_ == objectValue' failed.
解決方法:循環讀取數組
1: Json::Value friends = tempVal["friends"];
2: for(int i = 0;i < friends.size();i++)
3: {
4: cout << friends[i]["name"].asString() << endl;
5: }
1: Json::Reader *pJsonParser = new Json::Reader();
2: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\",\"sex\":\"男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";
3: Json::Value tempVal;
4: if(!pJsonParser->parse(strJson, tempVal))
5: {
6: return -1;
7: }
8: int name = tempVal["name"].asInt();
解決方法:先判斷類型,如果類型正確在取
1: if(tempVal["name"].isInt())
2: {
3:
4: int name = tempVal["name"].asInt();
5: }
對於SDK接入認證服務器而言,json解析完全依賴於渠道SDK傳過來的SDK,jsoncpp過於依賴json字符串,如果對端傳過來一個不合法的json,很容易引起認證服務器的崩潰,所以對於SDK認證而言,采用C++來解析json是一個不太好的選擇,此外SDK中的demo一般都只提供php或python的源代碼,還得自己翻譯,不太劃算,後面的SDK准備都采用php的方式進行接入。
Jsoncpp讀寫實例代碼
這裡Mark一下jsoncpp的讀寫實例代碼:
1: #include
2: #include "json/json.h"
3: #include
4: using namespace std;
5:
6: int main()
7: {
8: Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
9: //Json::Reader *pJsonParser = new Json::Reader();
10: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\",\"sex\":\"男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";
11: //string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":{\'name\':\'chen\',\'sex\':\'男\'}}";
12: //string strJson = "1111 {}";
13:
14: Json::Value tempVal;
15:
16:
17: if(!pJsonParser->parse(strJson, tempVal))
18: {
19: cout << "parse error" << endl;
20: return -1;
21: }
22:
23: string name = tempVal["name"].asString();
24: string sex = tempVal["sex"].asString();
25: string age = tempVal["age"].asString();
26:
27: Json::Value friends = tempVal["friends"];
28: for(int i = 0;i < friends.size();i++)
29: {
30: cout << friends[i]["name"].asString() << endl;
31: }
32:
33: cout << "name = " << name << " age = " << age << " sex = " << sex << " friendsName " << friendsName < 34:35: delete pJsonParser;36:37: return 0;38: }39:2.Write
1: #include2: #include3: #include "json/json.h"4: using namespace std;5:6: int main()7: {8: Json::Value root;9: Json::FastWriter writer;10: Json::Value person;11:12: person["name"] = "hello world";13: person["age"] = 100;14: root.append(person);15:16: std::string json_file = writer.write(root);17:18:19: ofstream ofs;20: ofs.open("test1.json");21: assert(ofs.is_open());22: ofs< 23:24: return 0;25: }
-
Echo Chen:Blog.csdn.net/chen19870707
-