CRT 入口函数 CRTStartup
windows啟動一個程序的過程大概是這樣的:首先由外殼程序(比如Explorer)調用CreateProcess這個系統調用,CreateProcess為這個進程創建虛擬地址,然后將代碼和數據載入,然后系統再創建一個主線程開始執行run time startup函數的代碼,run time startup 函數會最終調用入口點函數(main, WinMain)。
run time startup會做很多事情,比如全局變量的創建和銷毀,入口點函數的調用等。這里我就要有問題要問了,run time startup函數對于我編程來講是不可見的,那么這個函數到底在哪里呢?起初我還以為它在一個動態連接庫里,但馬上我就發現不對。在連接程序的時候我發現下面一條信息:
? Found _printf
 ??????? Referenced in temporary.obj
 ??????? Loaded LIBCD.lib(printf.obj)
 ????? Found _mainCRTStartup
 ??????? Loaded LIBCD.lib(crt0.obj)
很明顯,它是由libcd.lib靜態的連接到我的exe程序的。在網上搜了下相關的信息,發現了一個很有趣的程序,這個程序沒有WinMain函數,但卻能夠輸出字符串。程序如下:
//文件名:a.c
//不是原創
#include?< windows.h >
const char str[] = "This is Zouxiao's blog";
void DrawString(HDC hDC, int x, int y)
 {????
 ??? SetBkMode(hDC, TRANSPARENT);
 ??? SetTextColor(hDC, RGB(255, 0, 0));
 ??? TextOut(hDC, x, y, str, strlen(str));
 }
void WinMainCRTStartup()
 {
 ??? HDC hDC = GetDC(NULL);
??? DrawString(hDC, GetSystemMetrics(SM_CXSCREEN) / 2,
 ??????????????????? GetSystemMetrics(SM_CYSCREEN) / 2);
 ????
 ??? ReleaseDC(NULL, hDC);
}
成功的連接這個文件需要注意兩點:1,文件的后綴名必須為.c而不能是.cpp。 2,必須打開/SUBSYSTEM:WINDOWS的連接開關。
根據這個程序可以看出:
WinMainCRTStartup這個函數名是由連接器選定的,如果是/SUBSYSTEM指定的是windows,那么就是WinMainCRTStartup,如果/SUBSYSTEM指定的是console,那么就是mainCRTStartup。如果沒有指定的話連接器就自動根據入口點函數(main,WinMain)自動選擇,在這種情況下如果沒有入口點函數連接器就會報錯。CRTStartup函數并不用我們寫,在libc.lib(libcd.lib)中有一份編譯好了的CRTStartup函數(源代碼visual studio目錄中可以找到(crt0.c,wincrt0.c)),這個函數會默認的調用我們的入口點函數,而且連接器會自動將其連接到我們的exe程序(在我們文件里沒有這些函數的前提下)
大概我的理解就這么多,至于為什么它必需要以.c為后綴名,是因為它必須以c語言編譯,或許是因為它屬于c run time library ,連接器只識別以c語言編譯的函數的緣故吧
總結
以上是生活随笔為你收集整理的CRT 入口函数 CRTStartup的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: arm-eabi-gcc: error
- 下一篇: dalvik对于Java方法调用的实现
