1.ACE の紹介

1.3 ACE の構成

1.5 複数のOSにあなたのコードを移植する

ネットワークプログラムは異機種間で利用される場合が多い。その一方で各機種の構成は異なっている。これらのプラットフォーム間にわたって利用されている OS についても、それぞれ API にはいくらかの差異が存在する。
ACE は各 プラットフォーム・OS 間における移植を可能とするために熟慮された構成になっている。ACE_OS クラスメソッド群は低レベルAPIにおける差異を吸収し、広いプラットフォーム間でのコードの移植を可能としている。また、そのために利用されているファサードパターンにより、各関数は利用しやすいインターフェースを持つように修正されている。さらに、データ形式や各種マクロについてもACE内で名称が統一されており、サードパーティーによるマクロを利用しなければならない場合はほとんど無い。
これらの工夫により、複数 OS 間におけるコードの移植はかなり容易になっていると言える。

1.6 C++コンパイラ間の差異を吸収する

各メーカーや団体が提供している C++ コンパイラは、ほぼ C++ 標準に則って作成されているが、その準拠の程度や標準のドラフト時での対応度には違いがある。また、コンパイラの動作自体に問題がある場合もある。
特に以下の4点について問題になることが多いため、ACE ではこの点を考慮してライブラリを作成してある。

1.6.1 テンプレート

明示的なインスタンス化への対応状況により、コンパイラに適した文を生成するようになっている。
また、テンプレートパラメータのクラス型へアクセスできない古いコンパイラでもACEを利用できるようにマクロ等で対応している。

1.6.2 データタイプ

コンパイラとハードウェアの組み合わせにより、各データタイプのサイズは異なる場合がある。例えば、ある状況ではintが32ビットだが、他の状況ではintが16ビットかもしれない。このような差異が移植時に問題にならないように、ACE ではサイズごとにデータタイプに別名を付けてある。こちらの名前を利用することで、コンパイラおよびハードウェアに依存しないコーディングが可能となる。

1.6.3 実行時の初期化と終了処理

static 変数の初期化や終了における順序はC++標準で定められていない。このため、各コンパイラごとに違った実装になっている可能性が高い。
ACE ではこの問題に対して3つのクラスを用意することで対応している。一つ目は ACE_Object_Manager であり、これに各オブジェクトを登録しておくことで、アプリケーションの終了時に登録とは逆の順序で削除されることが保証される。
二つ目は ACE_Cleanup で、ACE_Object_Manager で管理するオブジェクトはこのクラスから継承する必要がある。この中で定義されている cleanup() メソッドによって実際の削除処理が行われる。このために必要なのは、大抵はコンストラクタ内での次の命令(ACE_Object_Manager.at_exit(this))をコールすることだけである。
三つ目は ACE_Singleton であり、これはテンプレートクラスとなっている。プログラム内で唯一かつグローバルなオブジェクトを用意したい場合に、そのクラス名を指定して typedef して利用する。その際、マルチスレッドへの対応の有無もポリシークラスで指定することになる。例としては次のように利用する。
typedef ACE_Singleton TheFoo;
Foo* pFoo = TheFoo.instance();

これらのクラスを利用する場合に守らなければならない規則が二つだけある。一つは絶対に exit() 関数で終了しないことだ。これをやってしまうと、ACE_Object_Manager によるオブジェクト管理において、終了時のクリーンアップをバイパスしてアプリケーションが終了してしまう。どうしても必要な場合は ACE_OS::exit() を利用すること。
二つ目は ACE_Object_Manager が正しく初期化、終了されるようにすることである。int main(int argc, char* argv[]) もしくは ACE_TMAIN をエントリポイントとしてアプリケーションを記述した場合には、ACE によって自動的に ACE_Object_Manager の初期化と終了が行われるようになっている。しかし、main() を利用しない場合(例えばWinMainを利用するなど)には明示的に ACE::init() と ACE::fini() を実行することで正しい動作をするようにしてやらなければならない。

1.6.4 ヒープメモリの割り当て

C++ 標準では、ヒープメモリの割り当てに new を利用するようになった。しかしながら、コンパイラによって割り当て失敗時に NULL ポインタを返すだけの場合と、例外を送出する場合に分かれてしまっている。これらを統一するために ACE ではマクロを定義してある。以下のマクロはどれもポインタ p にコンストラクタ c の内容で割り付ける。失敗した場合の動作のみ異なる。

1.7 1バイト、又は複数バイトの文字を利用する

文字コードはアメリカでは1バイトで十分だが、他の国によっては複数バイトで表現しなければならない場合がある。C++ では wchar_t 型によって複数バイト文字を表現するようになっている。ACE では、この切り替えを ACE_USES_WCHAR の定義の有無によって行えるようにいくつかのマクロを定義してある。

Index
Top