idnkitライブラリ (およびidnkitliteライブラリ) を用いたアプリケーション の作成方法や注意点をまとめました。
idnkitライブラリ (およびidnkitliteライブラリ) を使用したプログラムの 作成方法、および注意点などについてまとめておきます。
高レベルAPIを使用するプログラムでは、idn/api.h
を
インクルードしてください。
(エラーコードを定義しているidn/result.h
は、
idn/api.h
から暗黙的にインクルードされるため、明示的に
インクルードする必要はありません。)
#include <idn/api.h>
低レベルAPIを使用するプログラムでは、idn/res.h
を
インクルードしてください。
(変換コンテキストを操作するresconfモジュールのヘッダファイル
idn/resconf.h
やエラーコードを定義している
idn/result.h
は、idn/res.h
から暗黙的に
インクルードされるため、明示的にインクルードする必要はありません。)
#include <idn/res.h>
バージョン番号の取得関数を提供しているversionモジュールを使う場合は、
別途idn/version.h
をインクルードして下さい。
#include <idn/version.h>
idnkitライブラリ (およびidnkitliteライブラリ) は、実行時に、
ローカルエンコーディングや「現在の言語」を決定する際、ロケールの
設定情報を参照します。
そのため、アプリケーションは冒頭部分でsetlocale()
を
呼び出し、ロケールの初期化を行って下さい。
典型的な呼び出し方は、次のようになります。
setlocale(LC_ALL, "");
システムやCコンパイラによっては、setlocale()
を使用する
ためには
#include <locale.h>
という記述も別途必要かも知れません。 詳しくは、お使いのシステムないしCコンパイラのマニュアルを参照して下さい。
idnkitライブラリ (およびidnkitliteライブラリ) のほとんどのAPIは、
idn_result_t
型のエラーコードを返します。
エラーコードに応じたメッセージ文字列を返す関数
idn_result_tostring()
が用意されています。
エラーメッセージを表示する際には、この関数を使うと便利です。
ただし、エラーメッセージはロケール設定によらず英語になります。
idn_result_t r; /* idn_result_tostring() の使用例 */ r = idn_encodename(IDN_ENCODE_LOOKUP, from, to, tolen); if (r != idn_success) printf("error: %s\n", idn_result_tostring(r));
この関数についての詳細は、 「idn_result_tostring()」 をご覧ください。
アプリケーションをコンパイルする際には、idnkitのヘッダファイルの 配置場所をCコンパイラに伝える必要があるかも知れません。 もし、Cコンパイラがヘッダファイルを見つけられなかった場合は、
error: idn/api.h: No such file or directory
といったエラーメッセージが出力されます。
(メッセージは、お使いのCコンパイラ等によって異なります。)
GCCなど、UNIX系OSで動作する典型的なCコンパイラでは、
-I
オプションを使ってヘッダファイルの検索パスを指定
することができます。
たとえば、/usr/local/include/idn
の下にヘッダファイル
がインストールされている場合は (最後の/idn
を取って)、
gcc -I/usr/local/include -c sample.c
のようにします。
GCCに代表される、UNIX系OSで動作する典型的なCコンパイラを用いて
アプリケーションにidnkitライブラリをリンクする際は、-lidnkit
というオプションを付与します。
gcc -o sample sample.o -lidnkit
ただし、GNU libiconvなどの外部ライブラリの提供するiconv()
を利用した場合は、合わせてそのライブラリもリンクする必要があります。
たとえば、GNU libiconvであれば、次のようにします。
gcc -o sample sample.o -lidnkit -liconv
idnkitliteライブラリをリンクする際は、-lidnkit
の代わりに
-lidnkitlite
オプションを付与します。
idnkitliteライブラリはiconv()
を使用しませんので、
iconv()
を提供するライブラリのリンクは必要ありません。
gcc -o sample sample.o -lidnkitlite
ただし、idnkitライブラリ、idnkitliteライブラリ、iconv()
を提供するライブラリがすべて、Cコンパイラ (正確にはリンカ) が探し出せる
位置になくてはなりません。
見つからない場合は、
sample.c:(.text+0x19): undefined reference to `idn_nameinit'
といったエラーメッセージが出力されます。
その場合、
-L
オプションを使ってライブラリファイルの検索パスを
指定することができます。
たとえば、/usr/local/lib
の下にライブラリが
インストールされている場合は、
gcc -o sample sample.o -L/usr/local/lib -lidnkit
のようにします。 ただし、共有ライブラリをリンクする際は、さらに幾つかの注意点があります。 詳しくは次項に記します。
共有ライブラリをリンクする際、システムによってはコンパイラやリンカに オプションを付与する必要があります。 ただ、必要となるオプションは、システムによってまちまちです。 調べてもよく分からなければ、GNU libtoolを使うのも一つの手です。 (ただし、GNU libtoolが対応しているシステムに限ります。) GNU libtoolは以下のページから入手できます。
GNU libtoolを使用する場合、コンパイル時は次のように
"libtool --mode=compile
" に続けてCコンパイラのコマンド行を
記します。
libtool --mode=compile gcc -I/usr/local/include -c sample.c
同様に、リンク時は
"libtool --mode=link
" に続けてCコンパイラのコマンド行を
記します。
libtool --mode=link gcc -o sample sample.o -L/usr/local/lib -lidnkit
できあがったコマンドを所定のディレクトリにインストールする際は、
"libtool --mode=install
" に続けてinstallコマンドの
実行行を記します。
libtool --mode=install install -m755 sample /usr/local/bin
ここでは、高レベルAPIを使用して国際化ドメイン名の名前解決を行うための、 簡単なプログラムを紹介します。
#include <stddef.h> #include <sys/types.h> #include <stdio.h> #include <locale.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <idn/api.h> int main(int ac, char **av) { struct hostent *hp; char buf1[256]; char buf2[256]; char addr[100]; idn_result_t r; /* ロケールを設定する */ setlocale(LC_ALL, ""); if (ac != 2) { fprintf(stderr, "Usage: %s hostname\n", av[0]); return 1; } /* apiモジュールを初期化する */ if ((r = idn_nameinit(1)) != idn_success) { fprintf(stderr, "idn_nameinit: %s\n", idn_result_tostring(r)); return 1; } /* gethostbynameを呼ぶ前に名前を変換する */ if ((r = idn_encodename(IDN_ENCODE_LOOKUP, av[1], buf1, sizeof(buf1))) != idn_success) { fprintf(stderr, "idn_encodename: %s\n", idn_result_tostring(r)); return 1; } /* 名前解決を行う */ if ((hp = gethostbyname(buf1)) == NULL) { fprintf(stderr, "gethostbyname failed\n"); return 1; } /* 返された名前をローカルエンコーディングに変換する */ if ((r = idn_decodename(IDN_DECODE_LOOKUP, hp->h_name, buf2, sizeof(buf2))) != idn_success) { fprintf(stderr, "idn_decodename: %s\n", idn_result_tostring(r)); return 1; } inet_ntop(hp->h_addrtype, hp->h_addr, addr, sizeof(addr)); printf("%s %s\n", addr, buf2); return 0; }