动态链接到MFC的规则动态链接库被装载时下列过程的执行顺序(如果有的话):
1、构造全局对象、静态对象
2、调用对象的构造函数
3、RawDllMain
4、DllMain

解决方案 »

  1.   

    RawDllMain 
    全局对象的初始化,
    DllMain至于静态对象分地方,要使全局的话就跟全局对象一样,要使函数的话,就不是了。
      

  2.   

    贴出CRT的源码,看看顺序吧。/***
    *dllcrt0.c - C runtime initialization routine for a DLL with linked-in C R-T
    *
    *       Copyright (c) Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    *       This the startup routine for a DLL which is linked with its own
    *       C run-time code.  It is similar to the routine _mainCRTStartup()
    *       in the file CRT0.C, except that there is no main() in a DLL.
    *
    *******************************************************************************/#ifndef CRTDLL#include <cruntime.h>
    #include <dos.h>
    #include <internal.h>
    #include <mtdll.h>
    #include <stdlib.h>
    #include <string.h>
    #include <rterr.h>
    #include <oscalls.h>
    #define _DECL_DLLMAIN   /* enable prototypes for DllMain and _CRT_INIT */
    #include <process.h>
    #include <awint.h>
    #include <tchar.h>
    #include <dbgint.h>
    #include <rtcapi.h>
    #include <locale.h>
    static int __proc_attached = 0;char *_acmdln;              /* points to command line */char *_aenvptr = NULL;      /* points to environment block */
    wchar_t *_wenvptr = NULL;   /* points to wide environment block */int __error_mode = _OUT_TO_DEFAULT;
    int __app_type = _UNKNOWN_APP;extern BOOL WINAPI DllMain(
            HANDLE  hDllHandle,
            DWORD   dwReason,
            LPVOID  lpreserved
            ) ;extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID);
    extern BOOL (WINAPI * const _pDefaultRawDllMain)(HANDLE, DWORD, LPVOID) = NULL;
    #if defined (_M_IX86)
    #pragma comment(linker, "/alternatename:__pRawDllMain=__pDefaultRawDllMain")
    #elif defined (_M_IA64) || defined (_M_AMD64)
    #pragma comment(linker, "/alternatename:_pRawDllMain=_pDefaultRawDllMain")
    #else  /* defined (_M_IA64) || defined (_M_AMD64) */
    #error Unsupported platform
    #endif  /* defined (_M_IA64) || defined (_M_AMD64) */
    BOOL WINAPI _CRT_INIT(
            HANDLE  hDllHandle,
            DWORD   dwReason,
            LPVOID  lpreserved
            )
    {
            /*
             * Start-up code only gets executed when the process is initialized
             */        if ( dwReason == DLL_PROCESS_ATTACH )
            {
                if ( !_heap_init(1) )   /* initialize heap */
                    return FALSE;       /* fail to load DLL */            if(!_mtinit())          /* initialize multi-thread */
                {
                    _heap_term();       /* heap is now invalid! */
                    return FALSE;       /* fail to load DLL */
                }            /*
                 * Initialize the Runtime Checks stuff
                 */
    #ifdef _RTC
                _RTC_Initialize();
    #endif  /* _RTC */
                _acmdln = (char *)GetCommandLineA();
                _aenvptr = (char *)__crtGetEnvironmentStringsA();            if (_ioinit() < 0) {    /* initialize lowio */
                    _mtterm();          /* free TLS index, call _mtdeletelocks() */
                    _heap_term();       /* heap is now invalid! */
                    return FALSE;       /* fail to load DLL */
                }            if (_setargv() < 0 ||   /* get cmd line info */
                    _setenvp() < 0 ||   /* get environ info */
                    _cinit(FALSE) != 0) /* do C data initialize, but don't init floating point */
                {
                    _ioterm();          /* shut down lowio */
                    _mtterm();          /* free TLS index, call _mtdeletelocks() */
                    _heap_term();       /* heap is now invalid! */
                    return FALSE;       /* fail to load DLL */
                }            /* Enable buffer count checking if linking against static lib */
                _CrtSetCheckCount(TRUE);            /*
                 * increment flag to indicate process attach notification
                 * has been received
                 */
                __proc_attached++;
            }        else if ( dwReason == DLL_PROCESS_DETACH )
            {
                if ( __proc_attached > 0 )
                {
                    __proc_attached--;                /*
                     * Any basic clean-up code that goes here must be duplicated
                     * below in _DllMainCRTStartup for the case where the user's
                     * DllMain() routine fails on a Process Attach notification.
                     * This does not include calling user C++ destructors, etc.
                     */                if ( _C_Termination_Done == FALSE )
                        _cexit();#ifdef _DEBUG
                    /* Dump all memory leaks */
                    if (_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_LEAK_CHECK_DF)
                        _CrtDumpMemoryLeaks();
    #endif  /* _DEBUG */
                    /*
                     * What remains is to clean up the system resources we have
                     * used (handles, critical sections, memory,...,etc.). This
                     * needs to be done if the whole process is NOT terminating.
                     */#ifndef _DEBUG
                    if ( lpreserved == NULL )
                    {
    #endif  /* _DEBUG */
                        /*
                         * The process is NOT terminating so we must clean up...
                         */
                        /* Shut down lowio */
                        _ioterm();                    _mtterm();                    /* This should be the last thing the C run-time does */
                        _heap_term();   /* heap is now invalid! */
    #ifndef _DEBUG
                    }
    #endif  /* _DEBUG */
                }
                else
                    /* no prior process attach, just return */
                    return FALSE;
            }
            else if ( dwReason == DLL_THREAD_ATTACH )
            {
                _ptiddata ptd;            /* Initialize FlsGetValue function pointer */
                __set_flsgetvalue();            if ( ((ptd = _calloc_crt(1, sizeof(struct _tiddata))) != NULL))
                {
                    if (FLS_SETVALUE(__flsindex, (LPVOID)ptd) ) {
                        /*
                         * Initialize of per-thread data
                         */
                        _initptd(ptd, NULL);                    ptd->_tid = GetCurrentThreadId();
                        ptd->_thandle = (uintptr_t)(-1);
                    } else
                    {
                        _free_crt(ptd);
                        return FALSE;
                    }
                } else
                {
                    return FALSE;
                }
            }
            else if ( dwReason == DLL_THREAD_DETACH )
            {
                _freeptd(NULL);         /* free up per-thread CRT data */
            }        return TRUE ;
    }/***
    *BOOL WINAPI _DllMainCRTStartup(hDllHandle, dwReason, lpreserved) -
    *       C Run-Time initialization for a DLL linked with a C run-time library.
    *
    *Purpose:
    *       This routine does the C run-time initialization or termination
    *       and then calls the user code notification handler "DllMain".
    *       For the multi-threaded run-time library, it also cleans up the
    *       multi-threading locks on DLL termination.
    *
    *Entry:
    *
    *Exit:
    *
    *NOTES:
    *       This routine is the preferred entry point. _CRT_INIT may also be
    *       used, or the user may supply his/her own entry and call _CRT_INIT
    *       from within it, but this is not the preferred method.
    *
    *******************************************************************************/static
    BOOL __cdecl
    __DllMainCRTStartup(
            HANDLE  hDllHandle,
            DWORD   dwReason,
            LPVOID  lpreserved
            );BOOL WINAPI
    _DllMainCRTStartup(
            HANDLE  hDllHandle,
            DWORD   dwReason,
            LPVOID  lpreserved
            )
    {
            if (dwReason == DLL_PROCESS_ATTACH)
            {
         
                __security_init_cookie();
            }        return __DllMainCRTStartup(hDllHandle, dwReason, lpreserved);
    }
      

  3.   

    __declspec(noinline)
    BOOL __cdecl
    __DllMainCRTStartup(
            HANDLE  hDllHandle,
            DWORD   dwReason,
            LPVOID  lpreserved
            )
    {
            BOOL retcode = TRUE;        /*
             * If this is a process detach notification, check that there has
             * has been a prior process attach notification.
             */
            if ( (dwReason == DLL_PROCESS_DETACH) && (__proc_attached == 0) )
                /*
                 * no prior process attach notification. just return
                 * without doing anything.
                 */
                return FALSE;        __try {
                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 )
                        return FALSE;
                }            retcode = DllMain(hDllHandle, dwReason, lpreserved);            if ( (dwReason == DLL_PROCESS_ATTACH) && !retcode )
                {
                    /*
                     * The user's DllMain routine returned failure, the C runtime
                     * needs to be cleaned up. Do this by calling _CRT_INIT again,
                     * this time imitating DLL_PROCESS_DETACH. Note this will also
                     * clear the __proc_attached flag so the cleanup will not be
                     * repeated upon receiving the real process detach notification.
                     */
                    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()) ) {
                return FALSE;
            }        return retcode ;
    }#endif  /* CRTDLL */
      

  4.   

    1、构造全局对象、静态对象 
    2、调用对象的构造函数 
    3、RawDllMain 
    4、DllMain不知道你第2点说的对象是什么,其它3点应该没有错
      

  5.   

    是不是程序编译链接的时候系统会自动把源码加入到程序中,然后系统是调用_MainCRTStartup(可能是这个名字吧),然后再由_MainCRTStartup去调用main函数。
    我刚学不久啊,对这些东西实在有点搞!
      

  6.   

    原来winmain函数中的Hinstance等参数就是从CRT源码中传进去的是吧
      

  7.   

    VS自带,在crt目录,自己找
    VC6默认不安装,需要自己更改选项。