Windows應用程式初始化過程

來源:互聯網
上載者:User

Windows 應用程式必須有一個進入點函數,應用程式開始運行時,這個函數會被調用。C/C++開發人員可以使用以下兩種進入點函數:

Int WINAPI _tWinMain(    HINSTANCE hInstance,    HINSTANCE,    PTSTR pszCmdLine,    int nCmdShow);
int _tmain( int argc, TCHAR *argv[], TCHAR *envp[]);

具體的符號取決於我們是否要使用Unicode字串。作業系統實際上不會調用我們寫的進入點函數,他會調用由C/C++運行庫實現並在連結時使用-entry:命令列選項來設定一個C/C++運行時啟動函數。該函數將初始化C/C++運行庫,使我們能使用malloc和free之類的函數。它確保了在我們代碼開始執行前,我們聲明的任何全域和靜態c++對象都被正確的構造。

所有的C/C++運行庫啟動函數所做的事情基本都是一樣的,區別在於他們要處理的是ANSI字串,還是Unicode字串。以及在初始化C運行庫之後,他們調用的是哪個進入點函數。Visual C++內建C運行庫的原始碼。可以在crtexe.c檔案中找到4個啟動函數的原始碼。這些啟動函數的用途簡單總結如下:

  • 擷取指向新進程的完整命令列的一個指標。
  • 擷取指向新進程的環境變數的一個指標。
  • 初始化C/C++運行庫的全域變數。如果包括了StdLib.h,我們的代碼就可以訪問這些變數:_osver, _winmajor, _winminor, _argc,_argv等
  • 初始化C運行庫記憶體配置函數(malloc 和 calloc)和其他底層I/O常式使用的堆(heap)。
  • 調用所有全域和靜態C++類對象的建構函式。

完成所有這些初始化工作後,C/C++啟動函數就會調用應用程式的進入點函數。如果我門寫了一個_tWinMain函數,而且定義了_UNICODE,其調用過程將如下所示:

GetStartupInfo(&StartupInfo);int nMainRetVal=wWinMain((HINSTANCE)&__ImageBase,NULL,pszCommandLineUnicode,    (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ? StartupInfo.wShowWindow : SW_SHOWdEFAULT);

如果沒有定義_UNICODE,其調用過程將如下所示:

GetStartupInfo(&StartupInfo);int nMainRetVal=WinMain((HINSTANCE)&__ImageBase,NULL,pszCommandLineAnsi,    (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ? StartupInfo.wShowWindow : SW_SHOWdEFAULT);

注意,_ImageBase是一個連結器定義的偽變數,表明可執行檔被映射到應用程式記憶體的什麼位置。

如果我們寫了一個_tmain函數,而且定義了_UNICODE,那麼其調用過程如下:

int nMainRetVal=wmain(argc,argv,argp);

如果沒有定義_UNICODE,調用過程如下:

int nMainRetVal=main(argc,argv,argp);

使用Visual Studio嚮導產生的應用程式時,CUI應用程式的入口中沒有定義第三個參數(環境變數塊),如下所示:

int _tmain(int argc,TCHAR *argv[]);

如果需要訪問進程的環境變數,只需將上面調用換成

int _tmain(int argc,TCHAR *argv[],TCHAR *env[]);

這個env參數指向一個數組,數組中包含所有環境變數及其值,兩者用等號(=)分隔。

進入點函數返回後,啟動函數將調用C運行庫函數exit,向其傳遞傳回值(nMainRetVal)。

exit函數執行以下任務:

調用_onexit函數調用所註冊的任何一個函數。

調用所有全域和靜態C++類對象的解構函式。

在DEBUG產生中,如果設定了_CRTDBG_LEAK_CHECK_DF標誌,就通過調用_CrtDumpMemoryLeaks函數來產生記憶體泄露報告。

叫用作業系統的ExitProcess函數,向其傳入nMainRetVal。這會導致作業系統"殺死"我們的進程,並設定它的退出碼。

注意,為了安全起見,Microsoft並不贊成使用所有這些變數,因為使用了這些變數的代碼可能會在C運行庫初始化這些變數之前開始執行。我們應該直接調用對應的Windows API函數。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.