C/C++启动函数
今天在看《Windows核心编程》第四章,其中我感兴趣的是关于启动函数的描述。启动函数的用途如下:
1,获取指向新进程的完整命令行的一个指针;
2,获取指向新进程的环境变量的一个指针;
3,初始化C/C++运行库的全局变量
4,初始化所有全局和静态C++类对象的构造函数。
对于一个程序而言,在执行main函数之前会执行crtexe.c文件中mainCRTStartup或wmainCRTStartup函数,如下所示:
[html]
<span style="font-size:18px;">#ifdef WPRFLAG
int wmainCRTStartup(
#else /* WPRFLAG */
int mainCRTStartup(
#endif /* WPRFLAG */
#endif /* _WINMAIN_ */
void
)
{
/*
* The /GS security cookie must be initialized before any exception
* handling targetting the current image is registered. No function
* using exception handling can be called in the current image until
* after __security_init_cookie has been called.
*/
__security_init_cookie();
return __tmainCRTStartup();
}</span>
__tmainCRTStartup函数如下所示:
[html]
<span style="font-size:18px;">__declspec(noinline)
int
__tmainCRTStartup(
void
)
{
#ifdef _WINMAIN_
_TUCHAR *lpszCommandLine;
STARTUPINFO StartupInfo;
BOOL inDoubleQuote=FALSE;
__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_ */
/*
* Guard the initialization code and the call to user's main, or
* WinMain, function in a __try/__except statement.
*/
__try
{
/*
* There is a possiblity that the module where this object is
* linked into is a mixed module. In all the cases we gurantee that
* native initialization will occur before managed initialization.
* Also in anycase this code should never be called when some other
* code is initializing native code, that's why we exit in that case.
*
* Do runtime startup initializers.
*
* Note: the only possible entry we'll be executing here is for
* __lconv_init, pulled in from charmax.obj only if the EXE was
* compiled with -J. All other .CRT$XI* initializers are only
* run as part of the CRT itself, and so for the CRT DLL model
* are not found in the EXE. For that reason, we call _initterm,
* not _initterm_e, because __lconv_init will never return failure,
* and _initterm_e is not exported from the CRT DLL.
*
* Note further that, when using the CRT DLL, executing the
* .CRT$XI* initializers is only done for an EXE, not for a DLL
* using the CRT DLL. That is to make sure the -J setting for
* the EXE is not overriden by that of any DLL.
*/
void *lock_free=0;
void *fiberid=((PNT_TIB)NtCurrentTeb())->StackBase;
int nested=FALSE;
while((lock_free=InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, fiberid, 0))!=0)
{
if(lock_free==fiberid)
{
nested=TRUE;
 
补充:软件开发 , C语言 ,