dll加載過程全局變量會先初始化


在一個生成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只有一個初始化類對象作為全局變量進行初始化,其他需要初始化的對象在這個初始化類里順序初始化,這樣就可以保證初始化的順序了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM