不要告诉我从什么winmain之类的主函数开始这类话。DOS下输入程序名运行C程序时,好像是先运行一段编译器加的汇编代码(启动代码?),为我们的main之类的函数的运行做好准备工作,然后才跳到main运行。那么我们双击Windows程序图标之后发生了什么呢?

解决方案 »

  1.   

    操作系统干的事(到google上查一查这些函数):
    ZwCreateSection //创建文件的内存映象,生成一个内核对象
    ZwCreateProcess //创建一个进程
    ZwCreateThread //创建进程的主线程你的程序在main或者WinMain之前做的事这样查看:
    在你的App类的构造函数或者main函数中设置断点,然后看call stack,找到WinMainCRTStartup函数,设置断点,重新运行程序,跟踪查看。
      

  2.   

    建议你去看下 windows核心编程 里面我记得前面就有写
      

  3.   

    Inside The windows2000(win2000内部解密)
      

  4.   

    这个事情本身就很复杂,怎么简单说呢?
     Carapee(山豆根) 说的是对的,看看<<MFC深入浅出>>或许你会更加清楚!
      

  5.   

    《Dissecting MFC》中有一段Windows Process前因后果,很详细的介绍了。
    值得收藏。
      

  6.   

    int initret;
            int mainret;
            OSVERSIONINFOA *posvi;
            int managedapp;
    #ifdef _WINMAIN_
            _TUCHAR *lpszCommandLine;
            STARTUPINFO StartupInfo;
    #endif  /* _WINMAIN_ */
            /*
             * Dynamically allocate the OSVERSIONINFOA buffer, so we avoid
             * triggering the /GS buffer overrun detection.  That can't be
             * used here, since the guard cookie isn't available until we
             * initialize it from here!
             */
            posvi = (OSVERSIONINFOA *)_alloca(sizeof(OSVERSIONINFOA));        /*
             * Get the full Win32 version
             */
            posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
            (void)GetVersionExA(posvi);        _osplatform = posvi->dwPlatformId;
            _winmajor = posvi->dwMajorVersion;
            _winminor = posvi->dwMinorVersion;        /*
             * The somewhat bizarre calculations of _osver and _winver are
             * required for backward compatibility (used to use GetVersion)
             */
            _osver = (posvi->dwBuildNumber) & 0x07fff;
            if ( _osplatform != VER_PLATFORM_WIN32_NT )
                _osver |= 0x08000;
            _winver = (_winmajor << 8) + _winminor;        /*
             * Determine if this is a managed application
             */
            managedapp = check_managed_app();#ifdef _MT
            if ( !_heap_init(1) )               /* initialize heap */
    #else  /* _MT */
            if ( !_heap_init(0) )               /* initialize heap */
    #endif  /* _MT */
                fast_error_exit(_RT_HEAPINIT);  /* write message and die */#ifdef _MT
            if( !_mtinit() )                    /* initialize multi-thread */
                fast_error_exit(_RT_THREAD);    /* write message and die */
    #endif  /* _MT */        /*
             * Initialize the Runtime Checks stuff
             */
    #ifdef _RTC
            _RTC_Initialize();
    #endif  /* _RTC */
            /*
             * Guard the remainder of the initialization code and the call
             * to user's main, or WinMain, function in a __try/__except
             * statement.
             */        __try {            if ( _ioinit() < 0 )            /* initialize lowio */
                    _amsg_exit(_RT_LOWIOINIT);#ifdef WPRFLAG
                /* get wide cmd line info */
                _wcmdln = (wchar_t *)__crtGetCommandLineW();            /* get wide environ info */
                _wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();            if ( _wsetargv() < 0 )
                    _amsg_exit(_RT_SPACEARG);
                if ( _wsetenvp() < 0 )
                    _amsg_exit(_RT_SPACEENV);
    #else  /* WPRFLAG */
                /* get cmd line info */
                _acmdln = (char *)GetCommandLineA();            /* get environ info */
                _aenvptr = (char *)__crtGetEnvironmentStringsA();            if ( _setargv() < 0 )
                    _amsg_exit(_RT_SPACEARG);
                if ( _setenvp() < 0 )
                    _amsg_exit(_RT_SPACEENV);
    #endif  /* WPRFLAG */            initret = _cinit(TRUE);                  /* do C data initialize */
                if (initret != 0)
                    _amsg_exit(initret);#ifdef _WINMAIN_            StartupInfo.dwFlags = 0;
                GetStartupInfo( &StartupInfo );#ifdef WPRFLAG
                lpszCommandLine = _wwincmdln();
                mainret = wWinMain(
    #else  /* WPRFLAG */
                lpszCommandLine = _wincmdln();
                mainret = WinMain(
    #endif  /* WPRFLAG */
                                   GetModuleHandleA(NULL),
                                   NULL,
                                   lpszCommandLine,
                                   StartupInfo.dwFlags & STARTF_USESHOWWINDOW
                                        ? StartupInfo.wShowWindow
                                        : SW_SHOWDEFAULT
                                 );
    #else  /* _WINMAIN_ */#ifdef WPRFLAG
                __winitenv = _wenviron;
                mainret = wmain(__argc, __wargv, _wenviron);
    #else  /* WPRFLAG */
                __initenv = _environ;
                mainret = main(__argc, __argv, _environ);
    #endif  /* WPRFLAG */#endif  /* _WINMAIN_ */            if ( !managedapp )
                    exit(mainret);            _cexit();        }
            __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
            {
                /*
                 * Should never reach here
                 */            mainret = GetExceptionCode();            if ( !managedapp )
                    _exit(mainret);            _c_exit();        } /* end of try - except */        return mainret;
      

  7.   

    这是一个应用程序的实际入口处。在这个里面调用WINMAIN的。
    这个函数名字叫WinMainCRTStartup不信你可以自己反汇编看看是不是这样的。
      

  8.   

    比如,我编一个win32程序,因为不知道程序的实际加载地址,编译的时候变量地址或指针的值应该是逻辑上的相对的偏移量吧?如果是,这个相对的基址是什么呢?进一步链接的时候,是不是把“启动代码”也链上啊?如果是,那么这个时候的WinMain的地址也是相对的吧?上面两个“如果”,如果不是,那怎么个样子?