4.実行時情報の収集

多くのアプリケーションでは実行時の動作を設定することができる。このための二大アプローチがコマンドラインオプションと設定ファイルである。
コマンドラインオプションはアプリケーションの実行ごとに異なる情報を渡すために用いられる。例えば、FTP や TELNET のホスト名などが挙げられる。
一方、設定ファイルはホストやユーザに関係付けられた情報を、複数回の実行にまたがって保存しておける。例はサーバの listen ポート番号などである。
ACE ではこれらをサポートするために以下のクラスが用意されている。

4.1 コマンドライン引数と ACE_Get_Opt

ACE_Get_Opt クラスは ACE におけるコマンドラインオプション解釈ツールである。これは POSIX における getopt() とほぼ同様の働きをする。ただし、getopt() とは異なり、それぞれの ACE_Get_Opt インスタンスが独立して状態を持つため、再入可能となっている。また、引数リストはコンストラクタによる構築時に一度だけ渡せばよい。getopt() のようにイテレーションごとに引数リストを渡す必要は無いため簡単になっている。
ACE_Get_Opt は次の2種類のオプションを解釈できる。
  1. ダッシュ一つ(「-」)に続いた一文字のオプション群
  2. ダッシュ二つ(「--」)に続く長い名前のオプション
p.78 の例は「-f」もしくは「--config」に続くファイル名をオプションとして取得できるようなサンプルである。
この例ではコマンドラインオプションを解析するのに必要な手順が示されている。
引数が必要だが渡されなかった場合、短いオプション群で定義された文字列の最初の文字(例では「:」)に依存した動作となる。例の場合には「:」が返される。指定しなければ「?」が返ることになる。
引数を必要としない短いオプションについては、一つのダッシュに続いて連続して指定することができる。この時、最後のオプションのみは引数を取っても良い。
短い形式のオプションを認識できなかった場合には「?」が返される。
英数字以外の短い形式のオプションを指定したい場合や、長いオプションのみを有効にして対応する短い形式のオプションを用意しない場合には long_option() 関数を次のように利用する。
cmd_opts.long_option( ACE_TEXT("cool_option"), 42 );
これにより、operator() でイテレートする際の返り値が 42 になる。これを case 文で捕捉すれば、--cool_option の指定を認識できる。
また、長いオプションについては、それぞれが区別できる部分まで入力すれば、残りは省略可能である。先の例では「--coo」までで「--cool_option」を認識できる。

これらは ACE_Get_Opt の基本的な利用法であり、さらに高度なことを行う場合にはリファレンスを参照すること。

4.1.1 ACE_Get_Opt の動作の変更

ACE_Get_Opt のコンストラクタは省略可能引数を含めると次のようになっている。
ACE_Get_Opt( int argc, ACE_TCHAR* argv[], const ACE_TCHAR* optstring, int skip_args = 1, int report_errors = 0, int ordering = PERMUTE_ARGS, int long_only = 0 );
パースを任意のインデックスから始めたい
skip_args を指定することで、任意の argv インデックスからパースを開始できる。デフォルトの 1 は、通常は argv[0] のコマンド名が入るため、それをスキップするのに 1 となっている。
パース中のエラーを報告する
デフォルトではオプションのパース中にエラーが起きても適切な operator() の返り値を返すだけで、特別なことは行わない。しかし report_errors を 0 以外に設定すると、パースエラーが発生した場合に ACE_ERROR((LM_ERROR, エラー内容)) としてログ出力を行う。
長いオプションの別な指定方法
短いオプションの定義文字列中に「W」が含まれている場合、ACE_Get_Opt は「-Wfoo」を「--foo」が指定されたものと解釈するようになる。
長いオプションのみを許可
long_only が 0 以外に設定された場合、一つのダッシュの場合でも長いオプションを指定したものとして解釈される。先の例で long_only が指定されている場合、「--config」と「-config」は同等となる。

4.1.2 引数の順序指定について

前の節で ACE_Get_Opt の ordering の指定について触れていなかったので、ここで詳しく説明する。このパラメータは以下の値を取ることができ、それぞれ動作が異なる。
これらはコンストラクタの ordering に指定することで変更できるが、以下の場合は実行時に上書きされる。
POSIXLY_CORRECT 環境変数が指定されている場合、ordering は REQUIRE_ORDER となる。
オプション文字列の最初が「+」か「-」の場合にはそれぞれ REQUIRE_ORDER、RETURN_IN_ORDER となる。同時に指定された場合には後の方が有効となる。

4.2 設定ファイルの利用

最近の windows ではレジストリに、その他はファイルに設定を保存しておき、利用する場合がある。これには ACE_Configuration クラスが定義したインターフェースを元に、次の二つのクラスが利用できる。
どちらのケースでも設定値はセクションによって構造化され、各セクションはゼロ以上の設定値を持つ。各設定値は名前と型付きの値で構成される。
設定情報は読み取りのみでなく変更も可能ではあるが、頻繁に変更されるデータベースのような利用法は想定外なので行ってはいけない。
p.83-84 には設定ファイル名を config_file とした場合の例が掲載されている。コードは HAStatus セクションの ListenPort の値を取得するためのものである。

4.2.1 設定セクション

設定データはセクションによって階層的に管理される。各設定オブジェクトは root section という無名の最上位セクションを持っており、他のセクションは全てここに含まれる。階層は任意の深さにすることができる。

4.2.2 設定のバックストア

ACE_Configuration_Win32Registry クラスは windows レジストリに直接アクセスすることができ、windows API のラッパーとなっている。
一方、ACE_Configuration_Heap ではメモリマップ割り当て戦略を利用しているため、設定内容は可読形式ではなく、オンメモリ(バイナリ)フォーマットとなっている。そのため、ACE は設定情報のファイルとのやりとりのために二つのクラスを提供している。
一つ目は ACE_Registry_ImpExp クラスであり、こちらは設定値の型も含めてテキストフォーマットした形式でファイル化する。そのため、設定値の型情報も保持され、バイトオーダーの異なるプラットフォーム間でも利用できる。先の例で使っているのはこちらである。
二つ目は ACE_Ini_ImpExp クラスであり、これは昔の Windows INI ファイル形式でデータを格納する。これには設定値の型情報は含まれず、全てのデータが文字列形式として取り扱われる。
どちらのクラスもテキストファイルを利用するが、相互に変換することはできない。一度決めたら、そちらの形式を利用し続けることになるため、一般的には ACE_Registry_ImpExp を利用することを推奨する。どうしても INI ファイルを利用しなければならない時に ACE_Ini_ImpExp を利用するようにしよう。

4.3 引数ベクタの組み立て方

前々節において、メインプログラムの argc/argv のような引数ベクタを処理する方法を学んだ。しかし、時々は一つの長い文字列をパースしたい場合もでてくるだろう。こんな場合には ACE_ARGV クラスが便利である。
利用方法は、文字列を ACE_ARGV クラスのコンストラクタに渡してオブジェクトを生成し、ACE_Get_Opt にはそのオブジェクトの argc()/argv() を渡すようにすればよい。この例は p.85-86 に記載されている。
ACE_ARGV クラスの利用には ace/ARGV.h のインクルードが必要である。ACE_ARGV のもう一つの利点として、渡された文字列中の環境変数を展開できる点が挙げられる。例では「$HOSTNAME」の部分が同名の環境変数の値で置換されるわけである。この機能は ACE_ARGV コンストラクタの第二引数(省略可、省略時は1)に 0 を指定することで無効にできる。
この環境変数展開時の参照名は先頭に「$」が付加されるが、これは windows 環境でも同様となる。windows では本来は $ を利用しないので注意が必要である。また、置換される環境変数は、名称それ自体がトークンである必要がある。「$HOME/conf.txt」などのような形では(HOME環境変数は)展開の対象とはならない。

Index
Top