在一個生成dll的工程中看到一個文件只有一句全局變量初始化的代碼,很好奇為什么這句代碼在dll加載的時候就會執行,因此斷點調試發現
__declspec(noinline) BOOL __cdecl __DllMainCRTStartup( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ) { BOOL retcode = TRUE; __try { __native_dllmain_reason = dwReason; __try{ /* * If this is a process detach notification, check that there has * been a prior process attach notification. */ if ( (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);//全局變量初始化,順序貌似沒有保證 if ( !retcode ) __leave; } retcode = DllMain(hDllHandle, dwReason, lpreserved);//dll入口函數,就是平時咋們在dll里寫的 if ( (dwReason == DLL_PROCESS_ATTACH) && !retcode ) { /* * The user's DllMain routine returned failure. Unwind the init. */ DllMain(hDllHandle, DLL_PROCESS_DETACH, lpreserved); _CRT_INIT(hDllHandle, DLL_PROCESS_DETACH, lpreserved); if ( _pRawDllMain ) (*_pRawDllMain)(hDllHandle, DLL_PROCESS_DETACH, lpreserved); } if ( (dwReason == DLL_PROCESS_DETACH) || (dwReason == DLL_THREAD_DETACH) ) { if ( _CRT_INIT(hDllHandle, dwReason, lpreserved) == FALSE ) { retcode = FALSE ; } if ( retcode && _pRawDllMain ) { retcode = (*_pRawDllMain)(hDllHandle, dwReason, lpreserved); } } } __except ( __CppXcptFilter(GetExceptionCode(), GetExceptionInformation()) ) { retcode = FALSE; } } __finally { __native_dllmain_reason = __NO_REASON; } return retcode ; }
這就是dll加載過程中的部分代碼,重點文字標紅;因此可以發現全局變量在進入dllmain函數之前就要初始化了;
由此也可以延伸出一個問題,當全局變量初始化的時候相互依賴會造成bug,所以一個良好的設計是:
dll只有一個初始化類對象作為全局變量進行初始化,其他需要初始化的對象在這個初始化類里順序初始化,這樣就可以保證初始化的順序了
