json-c を使ってみる

JSONをCでハンドルする必要に迫られたので, ライブラリがないかと探してみたところ, json-cというものを発見. なんでも, リファレンスカウントでオブジェクトをハンドルしてくれるらしい.

C++でスマートポインタを使ってリファレンスカウントする話は大昔からあるが, Cだけでそんなことできるんだろうか? と思ったら, ユーザが明示的に関数でリファレンスを増減するようになっているようだ.

version 0.7をダウンロードして, コンパイルしてみた. Mac OS Xでは,

> ./configure
> make

でとりあえずビルドできた. できたライブラリは ./.libs 以下に展開される. libjson.a の他に, libjson.dylib ができている. Mac OS X 独自のものか? fileでそれぞれ調べてみるとこんな感じ.

> file .libs/libjson.a
.libs/libjson.a: current ar archive random library
> file .libs/libjson.dylib
.libs/libjson.dylib: Mach-O dynamically linked shared library i386

ライブラリとしては, make install して, pkg-config を使って
下のように使うことを推奨しているらしい.

CFLAGS += $(shell pkg-config --cflags json)
LDFLAGS += $(shell pkg-config --libs json)

でも普通に,

gcc -std=c99 -I ${C_JSON_DIR} -o xxx xxx.c -l ${C_JSON_DIR}/.libs/libjson.a

コンパイル, リンクできる.

使い方

> make check

とやるとチェック用のバイナリ test1, test2 がビルドされる.
このソースを見てみるとだいたい使い方が分かる.

パーズ

パーズには, json_tokener_parse を用いる.

  struct json_object *new_obj;
  new_obj = json_tokener_parse("{\"foo\": 1 , \"bar\":2, \"buzz\": 3}");
  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));

こんな感じ.

連想配列をトラバースするマクロも定義されている.

  json_object_object_foreach(new_obj, key, val)
	  printf("(key, val) = (%s, %s)\n", key, json_object_to_json_string(val));

こう書いておくと,

(key, val) = (foo, 1)
(key, val) = (bar, 2)
(key, val) = (buzz, 3)

こうなる. なかなか便利.

json_object

json_object は 型と値が入った構造体になっていて, 型を取り出したり,
中身を取り出したりすることができる. 整数であることを確認してから
中身を取り出すコードはこんな感じ.

  if (json_object_get_type(val) == json_type_int)
	  int i = json_object_get_int(val);
object を作る

JSONのオブジェクトをつくるには まず空のオブジェクトを作って, それにフィルしてやる.

new_obj = json_object_new_object();
json_object_object_add(new_obj, "foo", json_object_new_int(1));
json_object_object_add(new_obj, "bar", json_object_new_int(2));
json_object_object_add(new_obj, "buzz", json_object_new_int(3));

こんな感じ. 簡単.