【1】ios
windows程序分爲GUI程序好CUI程序,即Graphical User Interface和Console User Interfacewindows
在Visual Studio中,GUI程序的連接開關是/SUBSYSTEM:WINDOWS, GUI程序的連接開關是/SUBSYSTEM:CONSOLE數組
這是一個控制檯程序的設置。函數
windows程序的入口有如下兩種:spa
1 Int WINAPI _tWinMain( 2 HINSTANCE hInstanceExe, //進程實例句柄 3 HINSTANCE , /*hPreInstance*/ //以前的實例,總爲NULL 4 PTSTR, pszCmdLine, //命令行參數,包括exe名稱 5 int nCmdShow 6 ); 7 8 9 10 int _tmain( 11 int argc, //參數個數,包含exe 12 TCHAR *argv[], //每一個參數字符串 13 TCHAR *envp[] //進程環境變量指針數組 14 );
【2】命令行
可是在調用上述入口函數以前,系統會調用真正的入口函數來作一些初始化的工做,好比初始化全局變量和靜態C++對象的構造,下面說明了每種狀況下的真正的入口函數指針
ANSI--------_tWinMain(WinMain)------------WinMainCRTStartupcode
UNICODE---_tWinMain(wWinMain)-----------wWinMainCRTStartup對象
ANSI--------_tmain(Main)--------------------mainCRTStartupblog
UNICODE----_tmain(wMain)------------------wmainCRTStartup
上面四個真正的入口函數的源碼在C運行庫的crtexe.c文件中。
【3】
HINSTANCE和HMODULE相同,可相互替代,只是在16位windows時代有所不一樣。
加載到進程地址空間的每一個可執行文件和DLL都有一個惟一的實例句柄, HICON LoadIcon(HINSTANCE hInstance, PCTSTR pszZIcon)函數的做用是從實例句柄爲hInstance的文件中加載名爲pszIcon的圖標資源。
可執行文件的實例被看成(w)WinMain函數的第一個參數(見上文),即參數 hInstanceExe, 這個參數的實際值是一個內存基地址,但願將可執行文件的映像加載到進程地址空間中的這個位置。
Visual Studio鏈接器默認的基地址是0x00400000, 這是在win98下,可執行文件所能加載到的最低的地址。使用MS的鏈接器/BASE:address開關能夠更改基地址。
那麼怎麼樣得到一個可執行文件或DLL被加載到進程地址空間的什麼位置呢? 可用下函數:
HMODULE GetModuleHandle(PCTSTR pszModule)
加入A進程調用了一個可執行文件B和一個DLL名爲C, 那麼能夠用這個函數來把B 或 C的名字做爲pszModule參數傳給它取得B或C在當前進程地址空間中的位置, 若是找到了該參數標明的可執行文件或DLL,那麼將返回他們在進程地址空間中的位置,不然返回NULL。
若是給pszModule參數傳NULL, 那麼將返回調用此函數的進程即A進程的可執行文件的基地址。
1 #include "stdafx.h" 2 #include <iostream> 3 #include "windows.h" 4 5 int _tmain(int argc, _TCHAR* argv[]) 6 { 7 8 HMODULE hModue = GetModuleHandle(NULL); 9 10 printf("當前進程地址爲:0x%08x\n", hModue); 11 12 PWSTR lpParams = GetCommandLineW(); //取得命令行參數,包括exe 13 14 int count = 0; 15 16 PWSTR *pRet = CommandLineToArgvW(lpParams, &count); //命令行參數和參數個數,包括exe; 該函數內部分配內存, 返回指針數組(指針的指針) 17 18 for (int i = 0; i < count; ++ i) 19 { 20 std::wcout<<pRet[i]<<std::endl; 21 } 22 23 24 return 0; 25 }
輸出以下:
須要注意的是:上面函數CommandLineToArgvW在函數內部分配內存,且不釋放,通常狀況下是能夠接收的,可是若是想要手動釋放那部份內存也是能夠的
HeapFree函數能夠用來釋放那部份內存:
HeapFree(GetProcessHeap(), 0, pRet); //pRet爲上面CommandLineToArgvW函數的返回值。
1 PTSTR pszValue = NULL; 2 3 DWORD dwResult = GetEnvironmentVariable(_T("path"), pszValue, 0); 4 5 if (0 != dwResult) 6 { 7 pszValue = (PTSTR)malloc(size); 8 GetEnvironmentVariable(_T("path"), pszValue, size); 9 wcout<<pszValue<<endl; 10 11 free(pszValue); 12 }