(轉)winmain和main入口函數比較

來源:互聯網
上載者:User

標籤:

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入口函數比較

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.