進程與windows應用程序

進程

      一般進程可以定爲一個正在運行的程序的一個實例,
      一個內核對象,操作系統可以用它來管理進程。也是系統保存進程統計信息的地方。
      一個地址空間,其中包含了可執行文件和DLL模塊的代碼數據,同時包括動態內存分配,和線程堆棧和堆得分配。
      CPU的工作方式,是 一個進程可以有多個線程..然後CPU會輪流調度資源分配給各個線程,就像一個時鐘一樣。
     
關於Windows應用程序的組成

要點描述:

     1. GUI 和 CUI 分別表示 圖形和控制檯的界面,
     2./SUBSYSTEM:CONSOLE 和 /SUB-SYSTEM:WINDOWS 分別是控制檯和窗口的鏈接器開關
     3._tWinMain 圖形界面的入口點函數 和 _tmain 控制檯界面的入口點函數。

一、Windows一般可以建立兩種應用程序。
      1.GUI程序 - 圖形用戶界面 - 它使用的連接器開關是/SUBSYSTEM:CONSOLE
      2.CUI程序 - 控制檯界面 - 它使用的連接器開關是/SUB-SYSTEM:WINDOWS
      操作系統會加載並檢查可執行文件映像的文件頭,並獲取這個子系統值。
      根據子系統值來創建 一個符合要求的程序界面。
     
二、 Windows 應用程序 都會有個入口點函數,在程序運行時,函數會被調用。
     
      int WINAPI _tWinMain(
          HINSTANCE hInstanceExe,
          HINSTANCE,
          PTSTR pszCmdLine,
          int nCmdShow);

     int _tmain(
         int argc,
         TCHAR *argv[],
         TCHAR *envp[]);
        
         操作系統實際並不調用我們所寫的入口點函數。相反,它會調用由C/C++運行庫實現並鏈接時使用-entry:命令選項來設置
         的一個C/C++運行時啓動函數。該函數將初始化C/C++運行庫,使我們能調用malloc和free之類函數。
        
       應用程序類型和相應的入口點函數表

應用程序類型

入口點函數(入口)

嵌入可執行文件的啓動函數

處理ANSI字符和字符串的GUI應用程序

_tWinMain (WinMain)

WinMainCRTStartup

處理Unicode字符和字符串的GUI應用程序

_tWinMain (wWinMain)

wWinMainCRTStartup

處理ANSI字符和字符串的CUI應用程序

_tmain (Main)

mainCRTStartup

處理Unicode字符和字符串的CUI應用程序

_tmain (Wmain)

wmainCRTStartup

       
       當鏈接器正確選擇了C/C++運行庫啓動函數後,鏈接器會根據指定的鏈接器開關,尋找相應的入口點函數,否則會返回
       "unresolved external symbol"(無法解析的外部符號)錯誤。 不然一般會根據情況分別選擇 嵌入可執行文件的啓動函數。
      
       當然我們也可以從自己的項目中移除/SUBSYSTEM鏈接器開關,讓程序自動判斷應該使用哪個子系統。
       去啓動入口點函數 (WinMain, wWinMain, main, or wmain) 。
      
       VisualC++有自帶C運行庫的源碼。可以在ertex.c文件中找到 這4個啓動入口點函數源代碼。這些啓動函數的用途下面簡單說下:
       1.獲取指向心進程的完整命令行的一個指針。
       2.獲取指向新進程的壞境變量的一個指針。
       3.初始化C/C++運行庫的全局變量。如果包含了StdLib.h,我們的代碼就可以訪問這些變量。
       4.初始化C運行庫內存分配函數malloc和calloc和其他底層I/O歷程使用的堆。
       5.調用所有全局和靜態C++類對象的構造函數。
      

變量名稱

類型

描述和推薦使用的Windws函數

_osver

unsigned int

操作系統構建的版本號, 如Windows Vista RTM was build 6000. 所以, _osver 的值就是6000. 請換用 GetVersionEx.

_winmajor

unsigned int

以十六進制表示的Windows系統的主版本. 對於Windows Vista,該值爲6. 請換用GetVersionEx.

_winminor

unsigned int

以十六進制表示的Windows系統的主版本. 對於Windows Vista,該值爲0. 請換用GetVersionEx.

_winver

unsigned int

(_winmajor << 8) + _winminor. 請換用GetVersionEx.

__argc

unsigned int

命令行上傳遞的參數個數. 請換用 GetCommandLine .

__argv

__wargv

char

wchar_t

長度爲 __argc 的一個數組 ,其中含有指向 ANSI/Unicode 字符串指針.

數組中的每一項都指向一個命令行參數. 注意,如果定義了_UNICODE,__argv 就爲 NULL如果沒有定義__wargv 爲 NULL 請換用 GetCommandLine.

_environ

_wenviron

char

wchar_t

一個指針數組,這些指針指向ANSI/Unicode字符串. 數組中的每一項都指向一個環境字符串. 注意,如果沒定義_UNICODE ,_wenviron 就爲 NULL如果已經定義了_UNICODE, _environ is NULL。請換用GetEnvironmentStrings 或 GetEnvironmentVariable

_pgmptr

_wpgmptr

char

wchar_t

正在運行的程序的名稱及其ANSI/Unicode完整路徑.

注意,如果已經定義了 _UNICODE ,_pgmptr is NULL如果沒有定義——UNICODE,_wpgmptr is NULL 請換用GetModuleFileName, 將 NULL 作爲第一個參數傳給該函數。

       
       

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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是一個鏈接器定義的僞變量,可執行文件都被映射到應用程序內存中的什麼位置以後討論。
      
       現在 我們如果寫了一個_main函數,可以定義?_UNICODE其調用過程如下:
       int nMainRetVal = wmain(argc, argv, envp);
       沒定義_UNICODE,調用過程如下:
       int nMainRetVal = main(argc, argv, envp);
      
       另外注意用Visual Studio 生成的應用程序CUI是沒有入口點的第3個參數
       int _tmain(int argc, TCHAR* argv[]);
       要自己添加成
       int _tmain(int argc, TCHAR* argv[], TCHAR* env[])
       env參數指向一個參數,所有環境變量和值 都用等號(=)分隔。

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

發佈了209 篇原創文章 · 獲贊 6 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章