winmain和main入口函数比较

本文详细介绍了C/C++语言中main函数的参数argc和argv的含义,以及在命令行中如何传递参数。同时,讨论了Windows环境下WinMain函数的参数及其用途,包括hInstance、hPrevInstance、lpCmdLine和nCmdShow。文章还提到了在VS2008中设置调试参数的方法,并通过示例展示了如何获取和处理命令行参数。最后,指出GetCommandLine()与WinMain的LPSTRlpCmdLine参数的区别,并提供了一个自编函数来处理命令行参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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在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就完全可以了。如果程序中使用了WinMain的某个参数,那么也可以用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, "windowname", MB_OK | MB_ICONINFORMATION);
    return 0;
}

winmain
因为WinMain的cmdline不包含程序名,所以就什么也没有显示。
main版:

#include<windows.h>
int main(int argc,char *argv)
{
    MessageBox(NULL, GetCommandLine(), "windowname", MB_OK | MB_ICONINFORMATION);
    return 0;
}

main
用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);
}

原文链接:https://www.cnblogs.com/panlm/p/4387375.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值