【C++】jsoncppライブラリ問題一二
Jsonはデータ交換によく使われるデータフォーマットです.C++標準ライブラリにはJson標準の実装は含まれていないので、いくつかのサードパーティライブラリを使用して、jsoncppは一般的なライブラリです.仕事の中でよくjsoncppを使うため、このライブラリの問題が少なくないことを発見して、この文章は本意はこの関数ライブラリに深く突っ込みたいと思っていますが、証拠を探す過程で一部の問題がバージョンによるものであることを発見したので、問題についていくつか説明して、同じ問題に遭遇した友达を助けたいと思っています.
異常によるプログラム終了
これも私が仕事で出会った問題です.プログラムが不正なjson列を処理すると、直接サービスプログラムが終了し、
再掘削により,開発環境用のjsoncppバージョンは0.5であることが分かった.0であるため、異常処理メカニズムは元である.実はjsoncpp 0.8.3から異常処理を変更し、定義
If defined, indicates that Json use exception to report invalid type manipulation instead of C assert macro.
最新版の1.8.4において、
If non-zero, the library uses exceptions to report bad input instead of C assertion macros. The default is to use exceptions.
したがって、最も簡単な方法は、ライブラリを最新版にアップグレードすることです.いくつかの理由で関数ライブラリをアップグレードできない場合は、データを使用する前に厳格なデータチェックを行うことが最も妥当です.それ以外に良い方法はありません.
どのようなエラーが異常を引き起こす可能性があるかについては、
下手な使い方
「下手」と言うのは、主にAPIが古いためで、明らかに現代のC++の歩みに追いつかず、同時にC++の各種容器とのインタラクションが困難で、ほとんどの場合、人工的にコードを書く必要がある.例:直感的な初期化操作が欠けている 現代のC++はmapの初期化などの直感的な初期化を強化した.
しかし、jsoncppはこのようなjson定数の初期化を提供していません.
手動で構築するか、次の操作を行います.
直観性に欠ける.STL容器からJson構造への変換を提供しない
直接変換機能を提供できれば便利ですが…
全体的に、jsoncppが提供するAPIは使いにくく、上で使用するAPIはいずれも旧版のAPIであり、その提供する新版API
使いやすさでは、JSON for Modern C++がより良い選択です.
引き続き私の公衆番号の文章に注目してください.
異常によるプログラム終了
これも私が仕事で出会った問題です.プログラムが不正な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_ASSERT
JSON_FAIL_MESSAGE
・assert
と、異常に対応するコードを見つけて、どのような状況が異常を引き起こすのか、どのようなキャプチャ可能なのか、どのようなプログラムが終了するのかを知ることができます.下手な使い方
「下手」と言うのは、主にAPIが古いためで、明らかに現代のC++の歩みに追いつかず、同時にC++の各種容器とのインタラクションが困難で、ほとんどの場合、人工的にコードを書く必要がある.例:
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;
}
直観性に欠ける.
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であり、その提供する新版API
Json::CharReaderBuilder
・Json::StreamWriterBuilder
などの使いやすさも悪い.使いやすさでは、JSON for Modern C++がより良い選択です.
引き続き私の公衆番号の文章に注目してください.