【C++】jsoncpp庫問題一二

Json是數據交換經常使用的一種數據格式。C++標準庫並無包含任何Json標準的實現,因此咱們要藉助於一些第三方庫,jsoncpp就是一個經常使用的庫。因爲工做中常常用jsoncpp,發現這個庫問題很多,該篇文章本意是想深度吐槽一下這個函數庫,但在尋找證據的過程當中發現部分問題是由版本形成的,因此對問題進行一些說明,但願能幫助遇到一樣問題的朋友。ios

異常致使程序終止

這也是我在工做中遇到的問題:在程序處理非法json串時,直接致使服務程序終止,即便使用try塊包圍這段代碼,仍沒法成功捕獲異常。深刻閱讀它的實現代碼才發現,jsoncpp的異常處理是比較原始的,遇到異常直接assert,因此程序直接就終止了。對於簡單的小程序來講,這無可厚非,但對於後端服務來講,這個問題很是嚴重,由於形成了服務不可用。json

通過再度挖掘,發現開發環境用的jsoncpp版本是0.5.0,因此異常處理機制原始;實際上在jsoncpp 0.8.3開始就對異常處理進行了改變,經過定義JSON_USE_EXCEPTION宏改變了類型無效的行爲:小程序

If defined, indicates that Json use exception to report invalid type manipulation instead of C assert macro.

在最新版的1.8.4裏,JSON_USE_EXCEPTION=1已是默認行爲了,除了註釋錯誤仍然調用assert外,基本上其餘全部的錯誤都會拋出異常,再也不assert了:後端

If non-zero, the library uses exceptions to report bad input instead of C assertion macros. The default is to use exceptions.

因此,最簡單的方案就是將庫升級爲最新版。若是由於一些緣由沒法升級函數庫,那最穩妥的方式就是在使用數據以前進行嚴格的數據檢查,除此以外沒有其餘更好的方式。數組

對於哪些錯誤可能致使異常,在jsoncpp.cpp文件裏直接搜關鍵字JSON_ASSERTJSON_FAIL_MESSAGEassert,找到對應異常所在的代碼,可讓你知道哪些具體狀況會致使異常,以及哪些是可捕捉的,哪些會引發程序終止的。app

蹩腳的使用方式

說「蹩腳」,主要仍是由於它提供的API太老套,明顯沒跟上現代C++的步伐,同時跟C++的各種容器交互困難,大部分狀況須要人工寫代碼。好比:ide

  • 缺少直觀的初始化操做

現代C++加強了直觀的初始化,好比map的初始化函數

std::map<int,int> map {{1,1},{2,2}};

但jsoncpp並無提供這類json常量的初始化,咱們只能經過:ui

Json::Value root;
    Json::FastWriter writer;

    root["name"] = "ideami";

    std::string json = writer.write(root);

    std::cout << json << std::endl;

人工構造,或者使用:idea

Json::Reader reader;
    Json::Value root;
    std::string jsonStr = "{\"name\":\"ideami\"}";
    if (!reader.parse(jsonStr, root)) {
        return -1;
    }

缺少直觀性。

  • 不提供STL容器到Json結構的轉換

std::vector<int>類型的數組,若生成json數組,咱們只能:

#include <iostream>
#include "json/json.h"
#include <string>

int main() {
    std::vector<int> v {1,2,3,4};

    Json::Value array;
    Json::FastWriter writer;

    for (auto e : v)
    {
        array.append(e);
    }

    std::cout << writer.write(array) << std::endl;
}

若是能提供直接轉換的功能就方便了...

總體上,jsoncpp提供的API比較難用,上面用的API都是老版的API,其提供的新版APIJson::CharReaderBuilderJson::StreamWriterBuilder等易用性也不好。

在易用性上,JSON for Modern C++是一個更好的選擇。

請繼續關注個人公衆號文章
圖片描述

相關文章
相關標籤/搜索