【C言語】jansson.hでシリアライズ化と逆シリアル化する方法

C言語/C++

以前にC言語でJsonファイルを利用する機会があり、その時のメモ書きです。
以下では、Jsonファイルをシリアル化と逆シリアル化する方法を確認します。

janssonとは

C言語で使用できるJSONファイル読み込み用ライブラリのことです

はじめに

以下で紹介する内容はUbuntuでgccを使った場合の内容です。
まずはインストール方法です。

sudo apt-get install -y libjansson-dev

利用するときには、事前にインクルードします。

#include <jansson.h>
Checkポイント

libjanssonを使用する場合には、ビルド時にリンクオプション「-ljansson」を使用する必要があります。

gcc sample.c -ljansson

Jsonファイルサンプル

利用するJsonファイルのサンプルです。
ファイル名はconfig.jsonとします。

{
    "fileInfo": 
    {
        "file-name":"abcdefg.txt",
        "No":1,
        "ver":1.2
    },
    "array-section": 
    [
        {
            "No":1345
        },
        {
            "No":7890
        },
        {
            "No":9999
        }
    ]
}

Jsonファイルにシリアライズ化する方法

Jsonファイルをシリアライズ化する方法です。(jsonファイルの作成)
サンプルファイルと同じ内容を用意していきます。

#include <jansson.h>
#include <string.h>

int main(int argc, char* argv[]) {
	
	//ルート要素の作成
	json_t* json_root = json_object();

	//json要素をセット
	json_t* json_fileinfo = json_object();
	if (json_fileinfo) {
		//filename
		json_object_set(json_fileinfo, "filename", json_string("abcdefg.txt"));
		//number
		json_object_set(json_fileinfo, "number", json_integer((json_int_t)1));
		//ver
		json_object_set(json_fileinfo, "ver", json_real((double)1.2));
		//ルートにセット
		json_object_set(json_root, "fileInfo", json_fileinfo);
		json_decref(json_fileinfo);
	}
	//array-section
	json_t* json_array_section = json_array();
	if (json_array_section){
		int array_no[] = { 1345, 7890, 9999 };
		for (int i = 0; i < 3; i++) {
			json_t* section = json_object();
			json_object_set(section, "No", json_integer((json_int_t)array_no[i]));
			json_array_append(json_array_section, section);
		}
		json_object_set(json_root, "array-section", json_array_section);
		json_decref(json_array_section);
	}
	printf("%s\n", json_dumps(json_root, json_object_size(json_root)));
	// dump
	json_decref(json_root);
}

シリアライズ化の実行結果

補足

Jsonファイルに出力する方法

#include <stdio.h>

FILE* fp;
fp = fopen("configa.json", "w");
fprintf(fp, "%s", json_dumps(json_root, json_object_size(json_root)));
fclose(fp);

Jsonファイルを逆シリアライズ化する方法

Jsonファイルを逆シリアライズ化する方法です。(jsonファイルを読み込み)
まずは、Jsonファイルをロードする部分から。

int main() {
    json_t* json_root;
    json_error_t json_error;

    json_root = json_load_file("config.json",  0, &json_error);
    if ( !json_root ) {
        fprintf(stderr, "%s", json_error.text);
        exit(-1);
    }
    /*処理*/
    /*利用後に解放*/
    json_decref(json_root);
}
重要①

jsonファイルを読み込む方法です。
json_t* json_load_file(const char* path, size_t flags, json_error_t* error);
エラーの場合、NULLを返却されるので利用前にチェックしましょう。

重要②

利用後は、オブジェクトの解放を忘れずに行う。
void json_decref(json_t* json);

次は、逆シリアライズ化のサンプルコードです。

#include <jansson.h>
#include <string.h>


typedef struct {
	const char* filename;
	int number;
	double ver;
	int array[3];
} FileInfo;

int main(int argc, char* argv[]) {

	if (argc != 2) {
		printf("json file not set");
		exit(1);
	}
	
	//Jsonファイル読み込み
	json_t* json_root;
	json_error_t json_error;
	json_root = json_load_file(argv[1], 0, &json_error);
	if (!json_root) {
		fprintf(stderr, "%s", json_error.text);
		exit(-1);
	}

	//jsonファイルオブジェクトを取得
	FileInfo info;
	json_t* json_orign;
	json_orign = json_object_get(json_root, "fileInfo");
	if (json_orign) {
		json_t* json_value;
		//file-name
		json_value = json_object_get(json_orign, "file-name");
		info.filename = json_string_value(json_value);
		//No
		json_value = json_object_get(json_orign, "No");
		info.number = json_integer_value(json_value);
		//ver
		json_value = json_object_get(json_orign, "ver");
		info.ver = json_real_value(json_value);
		//dump
		json_decref(json_value);
		printf("filename:%s\nnumber:%d\nver:%f\n", info.filename, info.number,info.ver);
	}
	json_orign = json_object_get(json_root, "array-section");
	if (json_orign) {
		//array_section
		json_t* json_value;
		json_t* item;
		for (size_t i = 0; ; i++) {
			item = json_array_get(json_orign, i);
			if (!item) {
				break;
			}
			json_value = json_object_get(item, "No");
			if (json_value) {
				info.array[i] = json_integer_value(json_value);
				printf("No:%d\n", info.array[i]);
			}
			json_decref(json_value);
		}
	}
	// dump
	json_decref(json_root);
}
Point

objectからkeyに対応する値を取得する。
json* json_object_get(const json_t* object, const char* key);
キーが見つからずエラーの場合にはNULLが返却されるためチェックが必要な場合には忘れずに

各型のオブジェクトの取得方法

それぞれの型に応じた取得方法は以下です。

int型の値を取得

json_int_t json_integer_value(const json_t* integer);
jsonが整数でない場合には0が返却されます。

文字列型の値を取得

const char* json_string_value(const json_t* string);
jsonが文字列でない場合にはNULLが返却されます。

【補足】戻り値は読み取り専用であるが、変更できる状態で取得するためはどうするのか?

char buf[256];
json_value = json_object_get(json_orign, "file-name");
strcpy(buf, json_string_value(json_value));
double型の値を取得

double json_real_value(const json_t* real);
jsonが実数出ない場合には0.0が返却されます。

array型を取得

json_t* json_array_get(const json_t* array, size_t index);
引数arrayがNULLまたは引数indexが範囲外の場合にはNULLが返却されます。

逆シリアライズ化の実行結果

参考

以下が今回参考にしたJanssonドキュメントです。

API Reference — Jansson 2.8 documentation

コメント

タイトルとURLをコピーしました