現象
Microsoft Visual C++ .NET 2003、Microsoft Visual C++ 2005、または Microsoft Visual C++ 2008 でビルドされたアプリケーションが 128 個程度以上の DLL のロードを行った場合、LoadLibrary 関数が失敗する可能性があります。
本現象は、Fiber Local Storage (以下、FLS) をサポートした Microsoft Windows Server 2003 以降のオペレーティング システムで発生する可能性があります。
この問題が発生したときに GetLastError 関数で得られる詳細エラー コードは次の通りです。
1114 : ERROR_DLL_INIT_FAILED (ダイナミック リンク ライブラリ (DLL) 初期化ルーチンの実行に失敗しました。)
原因
1 プロセスあたりの FLS の最大値は 128 であるため、129 以上の FLS の割り当てを行おうとすると、この現象が発生します。
なお、FLS がサポートされていないオペレーティング システムでは、Thread Local Storage (以下、TLS) が使用されます。Microsoft Windows 2000 以降の TLS の最大値は 1088 です。 FLS は、通常 Fiber 内にて局所的に値を保持するために使用され、Thread よりも軽い処理を実行することから、TLS よりも少ない容量が設定されています。
回避策
アプリケーションで使用する DLL の Visual C++ コンパイル オプションとして /MT オプションを利用している場合は、/MD オプションに変更してリビルドを行います。
/MT オプションで静的に C ランタイム ライブラリを使用した場合、それぞれのモジュールごとに C ランタイム ライブラリのインスタンスが存在するため、DLL の数と同じ数の FLS が割り当てられます。
/MD オプションで動的に C ランタイム ライブラリを使用することにより、同じバージョンの C ランタイム ライブラリのインスタンスが 1 つとなり、FLS も DLL の数に関わらず、1 つ割り当てられます。
コンパイル オプションの変更手順は次のとおりです。
-
Visual C++ .NET 2003、Visual C++ 2005、または Visual C++ 2008 の Solution Explorer でプロジェクトを開きます。
-
プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。
-
[C/C++] フォルダをクリックします。
-
[コード生成] プロパティ ページをクリックします。
-
[ランタイム ライブラリ] プロパティを [マルチスレッド DLL (/MD)] に変更します。
状況
この動作は仕様です。