首页 > 代码库 > C++ json库jsoncpp 吐槽

C++ json库jsoncpp 吐槽

 

  • Author:Echo Chen(陈斌)
  • Email:chenb19870707@gmail.com
  • 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字符串不合法

       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());

    2.解析串为json数组

       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: }

    3.转型错误

       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. Read

       1: #include <iostream>
       2: #include "json/json.h"
       3: #include <string>
       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 <<endl;
      34:  
      35:     delete pJsonParser;
      36:  
      37:     return 0;
      38: }
      39:  

    2.Write

     

       1: #include <fstream>
       2: #include <cassert>
       3: #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<<json_file;
      23:  
      24:     return 0;
      25: }

    -

    Echo Chen:Blog.csdn.net/chen19870707

    -

    C++ json库jsoncpp 吐槽