唯一のグローバル変数が生成DLLプロジェクトに初期化されたファイルは、このコードは、DLLがロードされたときに実行されるので、ブレークポイントデバッグが発見される理由だろコードを参照してください。
__declspec(NOINLINE) BOOL __cdecl __DllMainCRTStartup( hDllHandleハンドル DWORD dwReason、 LPVOIDがlpreservedを ) { BOOLのRETCODE = TRUE。 __try { __native_dllmain_reason = dwReason。 __try { / * *これは、プロセスのデタッチ通知である場合は、そこにいることを確認してください *事前プロセスであっ通知を添付してください。 * / もし((dwReason == DLL_PROCESS_DETACH)&&(__proc_attached == 0 )){ RETCODE = FALSE。 __leave。 } IF(|| dwReason DLL_PROCESS_ATTACH dwReason == == DLL_THREAD_ATTACH){ IF (_pRawDllMain) RETCODE =(* _pRawDllMain)(hDllHandle、dwReason、lpReserved); IF (RETCODE) RETCODE = _CRT_INIT(hDllHandle、dwReason、lpReserved)。保証はありませんように。//グローバル変数の初期化シーケンスに見える 場合(!リターンコード) __leave; } RETCODE = のDllMain(hDllHandle、dwReason、lpReserved); // DLLエントリ機能、その書かれた中に、DLL内の通常大きな音である 場合((dwReason == DLL_PROCESS_ATTACH)&&! FALSE){RETCODE){ / * *ユーザーのDllMainルーチンがエラーを返しました。INITをおくつろぎください。 * / のDllMain(hDllHandle、DLL_PROCESS_DETACH、lpreserved)。 _CRT_INIT(hDllHandle、DLL_PROCESS_DETACH、lpreserved)。 もし(_pRawDllMain) ( * _pRawDllMain)(hDllHandle、DLL_PROCESS_DETACH、lpreserved)。 } もし、((dwReason == DLL_PROCESS_DETACH)|| (dwReason == DLL_THREAD_DETACH)){ 場合(_CRT_INIT(hDllHandle、dwReasonは、lpreserved)== RETCODE = FALSE。 } であれば(RETCODE && _pRawDllMain){ RETCODE =(* _pRawDllMain)(hDllHandle、dwReason、lpreserved)。 } } } __except(__CppXcptFilter(GetExceptionCode()、GetExceptionInformation())){ RETCODE = FALSE。 } } __finally { __native_dllmain_reason = __NO_REASON。 } 戻りRETCODE。 }
これは、コードのDLLローディング部分、赤いマークテキストの焦点であり、初期化する関数をDllMain内に入る前に、グローバル変数を見つけることが可能です。
バグの原因となりますグローバル変数の相互依存関係を初期化する場合にも、問題を延長することができ、とても良いデザインは、次のとおりです。
DLLのみ初期化クラスオブジェクトをグローバル変数として初期化され、他の人が初期化され、このクラスのオブジェクト初期化シーケンスを初期化する必要があるので、初期化シーケンスを保証することができます