C/C++語言中的main函數, 經常帶有參數argc, argv, 如下:
int main(int argc, char** argv)
int main(int argc, char* argv[]) //也可以是wchar_t 或 tchar
argc 是指命令行輸入參數的個數, argv存儲了所有的命令行參數. 在命令行下, 每兩個argv[n]之間以空格分隔.
如在命令行下輸入 test.exe a b
argc 爲 3
argv[0] 爲 "test.exe"
argv[1] 爲 "a"
argv[2] 爲 "b"
以下一個簡單的程序可以幫你看看argc, argv具體代表什麼.
#include <stdio.h>
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; i++)
{
printf("%s\n", argv[i]);//通過處理argv[0]可以獲得當前可執行程序所在的路徑哦。
}
return 0;
}
另外, vc環境下向程序傳遞參數可以在 Debugging -> command argument 下設置. (下面說的WinMain也一樣)
在VS2008下,右鍵要調試的項目—>Properties—>Debugging—>Command Arguments—>輸入你要輸入的參數即可。
WinMain函數的原型聲明如下:
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);
WinMain函數接收4個參數, 這些參數都是在系統調用WinMain函數時, 傳遞給應用程序的.
第一個參數hInstance表示該程序當前運行的實例的句柄, 這是一個數值. 當程序在Windows下運行時, 它唯一標識運行中的實例(注意, 只有運行中的程序實例, 纔有實例句柄). 一個應用程序可以運行多個實例, 每運行一個實例, 系統都會給該實例分配一個句柄值, 並通過hInstance參數傳遞給WinMain函數.
第二個參數hPrevInstance (MSDN)在Win32環境下, 這個參數不起作用,歷史遺留,hPrevInstance=NULL;
第三個參數lpCmdLine是一個以空('\0')終止的字符串, 指定傳遞給應用程序的命令行參數.
注: 運行參數,例如在命令行鍵入:test.exe /install,那麼程序入口WinMain處,其參數lpCmdLine就接收到了/install參數。但是,至於你用這個參數做什麼,那是用代碼實現,你即時對/INSTALL參數做了一個"uninstall"的處理,也是可以的。而實現安裝,這需要根據你的需求加入代碼,和命令行參數無關。
這個跟命令行的int main(int argc, char* argv[])不同
如上文test.exe a b
lpCmdLine 爲 "a b"
第四個參數nCmdShow指定程序的窗口應該如何顯示, 例如最大化、最小化、隱藏等. 這個參數的值由該程序的調用者所指定, 應用程序通常不需要去理會這個參數的值.
注意:C語言的Windows API編程,並不一定需要使用WinMain入口函數。
如果不使用WinMain的四個參數,那麼直接使用main代替WinMain就完全可以了。
如果程序中使用了WinManin的某個參數,那麼也可以用main替代,但是需要增加WinMain的四個參數作爲變量,如下所示:
main()
{
....
HINSTANCE hInstance;
int iCmdShow;
LPTSTR szCmdLine;
hInstance=GetModuleHandle(NULL); //獲取程序本身的實例句柄
iCmdShow=SW_SHOWNORMAL;//定義窗口顯示模式
szCmdLine=GetCommandLine();//獲取命令行字符串
(hPrevInstance=NULL;一般程序用不到這個參數)
....
}
不過有一點要說明的就是GetCommandLine()函數返回的命令行參數帶有執行程序本身的名字,而WinMain的參數LPSTR lpCmdLine是不包含執行程序的名字本身的。
用main代替WinMain除了命令行參數是否包含程序本身名字這一點外,其他未發現不同。
測試一下,就用一個最簡單程序:
WinMain版:
#include<windows.h>
int WINAPI WinMain(HINSTANCE h1,HINSTANCE h2,LPTSTR cmdline,int cmdshow)
{
MessageBox(NULL,
cmdline,
"CmdLine",
MB_OK | MB_ICONINFORMATION);
return 0;
}
因爲WinMain的cmdline不包含程序名,所以就什麼也沒有顯示。
main版:
#include<windows.h>
int main(int argc,char *argv)
{
LPTSTR cmdline; //要用到這個參數,就用變量代替原來的參數
cmdline=GetCommandLine();//獲取命令行字符串,包括程序名本身
MessageBox(NULL,
cmdline,
"CmdLine",
MB_OK | MB_ICONINFORMATION);
return 0;
}
用main代替WinMain除了命令行參數是否包含程序本身名字這一點外,其他未發現不同。
測試了《Windows程序設計第五版》中的幾個程序,都可以正常運行。
最後補充說明:對於iCmdShow還可以不在程序中指定,由系統輸入獲得:
STARTUPINFO StartupInfo;
memset(&StartupInfo,0,sizeof(STARTUPINFO));
GetStartupInfo(&StartupInfo);
iCmdShow = (int)StartupInfo.wShowWindow;//獲取窗口顯示模式
另外爲了獲得更準確的cmdline,可以自編一個函數,不過我自編的這個函數,會去掉命令行中多餘的空格:
//用這個函數可以返回去掉了多餘空格的szCmdLine
LPTSTR GetCmdLine(int argc,char *argv[])
{
int i=0;
int length=0;
char * cmdline;
if(argc<2)
return TEXT("");
for(i=1; i<argc; i++)
{
length=length + strlen(argv[i]);
}
cmdline = (char *)malloc(sizeof(char)*(length + argc -1));
strcpy(cmdline,argv[1]);
if(argc>2)
{
for(i=2;i<argc;i++)
{
strcat(cmdline," ");
strcat(cmdline,argv[i]);
}
}
return TEXT(cmdline);
}