VC9的默认入口函数源码:
__declspec(noinline)
int
__tmainCRTStartup(
void
)
{
int initret;
int mainret=0;
int managedapp;
#ifdef _WINMAIN_
_TUCHAR *lpszCommandLine;
STARTUPINFO StartupInfo;
__try {
/*
Note: MSDN specifically notes that GetStartupInfo returns no error, and throws unspecified SEH if it fails, so
the very general exception handler below is appropriate
*/
GetStartupInfo( &StartupInfo );
} __except(EXCEPTION_EXECUTE_HANDLER) {
return 255;
}
#endif /* _WINMAIN_ */
/*
* Determine if this is a managed application
*/
managedapp = check_managed_app();
if ( !_heap_init(1) ) /* initialize heap */
fast_error_exit(_RT_HEAPINIT); /* write message and die */
if( !_mtinit() ) /* initialize multi-thread */
fast_error_exit(_RT_THREAD); /* write message and die */
/* Enable buffer count checking if linking against static lib */
_CrtSetCheckCount(TRUE);
/*
* 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);
/* get wide cmd line info */
_tcmdln = (_TSCHAR *)GetCommandLineT();
/* get wide environ info */
_tenvptr = (_TSCHAR *)GetEnvironmentStringsT();
if ( _tsetargv() < 0 )
_amsg_exit(_RT_SPACEARG);
if ( _tsetenvp() < 0 )
_amsg_exit(_RT_SPACEENV);
initret = _cinit(TRUE); /* do C data initialize */
if (initret != 0)
_amsg_exit(initret);
#ifdef _WINMAIN_
lpszCommandLine = _twincmdln();
mainret = _tWinMain( (HINSTANCE)&__ImageBase,
NULL,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow
: SW_SHOWDEFAULT
);
#else /* _WINMAIN_ */
_tinitenv = _tenviron;
mainret = _tmain(__argc, _targv, _tenviron);
#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;
}
这个mainCRTStartup的总体流程就是:
(1)初始化启动信息。
(2)初始化堆。
(3)初始化I/O。
(4)获取命令行参数和环境变量。
(5)初始化C库的一些数据。
(6)调用main并记录返回值。
(7)检查错误并将main的返回值返回。