• 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只有一个初始化类对象作为全局变量进行初始化,其他需要初始化的对象在这个初始化类里顺序初始化,这样就可以保证初始化的顺序了

  • 相关阅读:
    The type or namespace name 'Windows' does not exist in the namespace....
    WCF 事件处理
    ASP.Net程序在IIS7的部署问题
    Oracle Package的全局变量与Session
    [ASP.NET]C1Webgrid中实现编辑和计算
    EXCEL妙用:选取单元格时改变整行的背景色
    [转]22 个精美的网站管理后台模板推荐
    [转]C#开发Active控件(二)
    Oracle获取时间差的技巧
    C#里的Random
  • 原文地址:https://www.cnblogs.com/likemao/p/11226437.html
Copyright © 2020-2023  润新知