【C++】jsoncppライブラリ問題一二

2864 ワード

Jsonはデータ交換によく使われるデータフォーマットです.C++標準ライブラリにはJson標準の実装は含まれていないので、いくつかのサードパーティライブラリを使用して、jsoncppは一般的なライブラリです.仕事の中でよくjsoncppを使うため、このライブラリの問題が少なくないことを発見して、この文章は本意はこの関数ライブラリに深く突っ込みたいと思っていますが、証拠を探す過程で一部の問題がバージョンによるものであることを発見したので、問題についていくつか説明して、同じ問題に遭遇した友达を助けたいと思っています.
異常によるプログラム終了
これも私が仕事で出会った問題です.プログラムが不正なjson列を処理すると、直接サービスプログラムが終了し、tryブロックでこのコードを囲んでも、異常のキャプチャに成功しません.実装コードを深く読んでみると、jsoncppの異常処理は比較的原始的で、異常に直接assert遭遇したため、プログラムは直接終了した.簡単なウィジェットでは、これは間違いありませんが、バックエンドサービスでは、サービスが利用できないため、この問題は非常に深刻です.
再掘削により,開発環境用の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と、異常に対応するコードを見つけて、どのような状況が異常を引き起こすのか、どのようなキャプチャ可能なのか、どのようなプログラムが終了するのかを知ることができます.
下手な使い方
「下手」と言うのは、主にAPIが古いためで、明らかに現代のC++の歩みに追いつかず、同時にC++の各種容器とのインタラクションが困難で、ほとんどの場合、人工的にコードを書く必要がある.例:
  • 直感的な初期化操作が欠けている
  • 現代のC++はmapの初期化などの直感的な初期化を強化した.
    std::map map {{1,1},{2,2}};

    しかし、jsoncppはこのようなjson定数の初期化を提供していません.
        Json::Value root;
        Json::FastWriter writer;
    
        root["name"] = "ideami";
    
        std::string json = writer.write(root);
    
        std::cout << json << std::endl;

    手動で構築するか、次の操作を行います.
        Json::Reader reader;
        Json::Value root;
        std::string jsonStr = "{\"name\":\"ideami\"}";
        if (!reader.parse(jsonStr, root)) {
            return -1;
        }

    直観性に欠ける.
  • STL容器からJson構造への変換を提供しない
  • std::vectorタイプの配列のように、json配列を生成するには、次のようにするしかありません.
    #include 
    #include "json/json.h"
    #include 
    
    int main() {
        std::vector 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++がより良い選択です.
    引き続き私の公衆番号の文章に注目してください.