標籤:
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);
}
參考:http://blog.163.com/[email protected]/blog/static/99751486201212345130881/
(轉)winmain和main入口函數比較