您的位置:首页 > 大数据 > 人工智能

(转)winmain和main入口函数比较

2015-04-02 16:34 357 查看
C/C++语言中的main函数, 经常带有参数argc, argv, 如下:

int main(int argc, char** argv)

int main(int argc, char* argv[]) //也可以是wchar_t 或 tchar

argc 是指命令行输入参数的个数, argv存储了所有的命令行参数. 在命令行下, 每两个argv
之间以空格分隔.

如在命令行下输入 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/hanyinlong@126/blog/static/99751486201212345130881/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: