初期化処理

nine core の初期化タイミング

nineライブラリは C++ の大域変数生成を利用して初期化、後始末処理を行っている。

大域変数は main() の前に構築されるため、main() 以降で nine の機能を利用する際はアプリケーションで特に行う事は無い。

大域変数利用上の問題

C++ 仕様では別のオブジェクトファイルで定義された大域変数の初期化順序は規定されていない。

以下のように、大域変数で nine を呼び出す場合は注意が必要である:

#include <nine/nine.h>
class MyServer: public nine::MessageServer
{
   ...
};
MyServer gMyServer;

gMyServer は nine::MessageServer のサブクラスであるので、コンストラクタの中で nine のコードが実行される。

ここで gMyServer は大域変数である。nine 初期化用の大域変数とどちらが先に構築されるかはリンカに依存する。 nine 初期化の前に gMyServer の構築が行われると、ランタイムエラーが起きる可能性がある。

nineの明示的な初期化

上述の問題を解決するために、nine は明示的な初期化方法を提供している。 nine::Initializerクラス がそれであり、インスタンスを作るだけで初期化を行ってくれる。

同一ファイル内の大域変数の初期化順序は規定されているので、以下のようにコードを修正すれば正しく nine から初期化させることができる。

#include <nine/nine.h>
class MyServer: public nine::MessageServer
{
   ...
};

nine::Initializer gNineInit;
MyServer gMyServer;

初期化・終了時のフック

nine は初期化・終了時にフック関数を呼び出す。 フック処理が不要でも、これらの関数をアプリケーション側で実装する必要がある。

フック関数の種類とそれぞれの呼ばれるタイミングは以下の通りである:

void PreInitialize(nine::Config& cfg)
nine初期化処理を行う前に呼ばれる。
nine は引数に渡した Config を用いて初期化を行う。初期化パラメータの変更は、この PreInitialize 内で cfg を変更することで行う。
void PostInitialize(const nine::Config& cfg)
nine初期化処理を行った後に呼ばれる。
引数の Config は、初期化した際の実際の設定内容である。
void PreFinalize()
nine終了処理を行う前に呼ばれる。
void PostFinalize()
nine終了処理を行った後に呼ばれる。
初期化フックの典型的な使い方はログ出力の停止である。アプリケーションで次のように記述すればよい:
namespace nine {
  void PreInitialize(nine::Config& cfg) {
    cfg.logType = nine::Config::LOG_NONE;
  }
}