從今天開始說說進程 進程通常被定義為一人正在啟動並執行程式的執行個體,它由兩個部分組成:1. 一個是作業系統用來管理進程的核心對象,核心對象也是系統用來存放關於進程的統計資訊的地方。2. 另一個是地址空間,它包含所有可執行模組或DLL模組的代碼和資料。它還包含動態記憶體分配的空間。如線程堆棧和堆分配空間。 要使進程完成某項操作,它必須要有一個自已的線程,來執行包含在此進程的地址空間中的代碼。每個線程都有它自已的一組CPU寄存器和它自已的堆棧。 多個線程是如何啟動並執行呢,作業系統為每個線程安排一定的CPU,通過一種迴圈方式為線程式提供時間片(稱為量稱) Windows支援兩種類型的應用程式。一種是基於圖形化使用者介面(GUI)的應用程式,另一種是基於控制台使用者介面(CUI)的應用程式。 在vc設定裡的連結程式根據 /SUBSYSTEM:CONDOLE還是/SUBSYSTEM:WINDOWS,當使用者運行一個應用程式時,os的載入程式查看可執行圖形程式的標題,並抓取該子系統的值,如果該值指明一個CUI應用程式,那麼載入程式就會自動保證為該應用程式建立文本控制台視窗。反之載入應用程式,當應用程式啟動運行後,os就不再關心應用程式擁有什麼類型的使用者介面了。 Windows提供的四個應用程式啟動運行時調用的進入點函數Int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE, PSTR pszCmdLine, int nCmdShow);//第二個參數表示前一個執行個體控制代碼,它是用在16位windows上的Int WINAPI wWinMain(HINSTANCE hinstExe, HINSTANCE, PWSTR nszCmdLine, int nCmdShow);l Int _cdecl main(int argc, char *agrv[], char *envp[]); Int _cdecl wmain(int argc, wchar_t *argv[], wchar_t *envp[]); 注意:os並不調用我們編寫的進入點函數,它是調用的是c/c++運行期啟動函數。該 函數負責對c/c++運行期庫進行初始化, 這樣,就可以調用malloc和free之類的函數。它還能確保已經聲名的任何全域對象和靜態c++對象能夠在代碼執行之前正確的建立。
應用程式的進入點
應用程式類型 進入點 嵌入可執行檔的啟動函數需要ASCI字元和字串的GUI應用程式 WinMain WinMainCRTStartup需要UNICODE字元和字串的GUI應用程式 wWinMain wWinMainCRTStartup需要ASCI字元和字串的CUI應用程式 main mainCRTStartup需要UNICODE字元和字串的CUI應用程式 wmain wmainCRTStartup 所有的c/c++運行期啟動函數的作用都是相同的,只不過處理ANSI字串還是Unicode字串,以及它們在對C運行期庫進行初始化後它們調用哪個進入點函數。
C運行期庫的原始碼在CRt0.c檔案裡其主要功能如下:1. 檢索指向新進程的完整命令列的指標.2. 檢索指向新進程的環境變數的指標。3. 對c/c++運行期的全域變數進行初始化。如果包含了StdLib.h檔案,代碼就能訪問這些變數了(WinMain等那四個函數)4. 對C運行期記憶體單元分配函數(malloc和calloc)和其它低層輸入/輸出常式使用的記憶體棧進行初始化。5. 為所有全域和靜態c++類對象調用建構函式。完成以上的功能後,c/c++啟動函數就調用應用程式的進入點函數。 進入函數返回時,啟動函數便調用c運行期的exit函數,exit函數負責如下的操作1. 調用由_onexit函數的調用而註冊的任何函數2. 為所有全域的和靜態c++類對象調用解構函式。3. 調用OS的ExitProcess函數. 待續.............