用C/C++编写的Windows GUI应用程序将'WinMain'作为入口点(而不是'main').我对此的理解是编译器生成一个'main'函数,由C Runtime调用.这个'main'函数为GUI设置必要的环境并调用'WinMain'(指定实例句柄等).
简而言之,我认为控制台和GUI应用程序的启动方式有以下不同之处:
控制台应用程序:C运行时 - >'主'功能(手动编码)
GUI应用程序:C运行时 - >'main'函数(编译生成) - >'WinMain'函数(手工编码)
我想验证这种理解并找出如何用一个'main'函数手动编写Windows GUI(即无需编写'WinMain').
你的理解不正确.main和WinMain之间的区别,除了一些不同的初始化代码,是传递给它的参数.
主要看起来像这样:
int main(int argc, char* argv[]);
虽然WinMain看起来像这样:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
有些东西必须设置这些参数并进行调用,这就是启动代码.编译和链接程序时,其中一个链接器参数是入口点,根据控制台或GUI应用程序,它将是不同的启动代码.
您当然可以编写自己的启动代码,只需进入visual c ++源目录,就可以找到启动代码,它叫做crt0.c,它位于VC\crt\src目录下.
使用Just main,您无法编写Winmain代码.为了证明理由,以下声明来自 http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx
[在Windows编程中,为什么应用程序入口点不是main?好吧,首先,名称main已经被采用,Windows没有权限保留备用定义.当时没有C语言标准化委员会; C就是Dennis所说的,并且几乎不能保证Dennis会采取任何特殊措施来保留未来C语言版本中的Windows源代码兼容性.由于K&R未指定实现可以扩展主函数的可接受形式,因此完全有可能存在合法的C编译器拒绝声明主要错误的程序.当前的C语言标准明确允许main的特定于实现的备用定义,
如果你设法克服了这个障碍,你就会遇到以下问题:Windows版本的main必须是这样的:
int main(int argc, char *argv[], HINSTANCE hinst, HINSTANCE hinstPrev, int nCmdShow);由于C链接的执行方式,函数的所有变体必须在它们共有的参数上达成一致.这意味着Windows版本必须将其参数添加到main的最长现有版本的末尾,然后您必须指责并希望C语言从未添加另一个备用版本的main.如果你走这条路线,你的交叉手指就会失败,因为事实证明第三个参数在一段时间后被添加到main中,并且它与你友好的Windows版本相冲突.
假设你设法说服Dennis不要允许那个三参数版本的main.您仍然必须提出前两个参数,这意味着每个程序的启动代码都需要包含命令行解析器.在16位的日子里,人们吝啬地保存每一个字节.告诉他们,"哦,你所有的节目都要大2KB"可能不会让你成为很多朋友.我的意思是,这是软盘上I/O的四个扇区!
但是,Windows入口点被赋予不同名称的原因可能是强调它是一个不同的执行环境.如果它被称为main,人们将采用专为控制台环境设计的C程序,将它们放入Windows编译器,然后运行它们,带来灾难性的结果.
希望这能清除你的疑虑.
它以另一种方式工作.有一个静态链接的目标文件,它带有保存实际入口点的编译器.该入口点进行初始化,然后调用您的入口点(即WinMain).
静态部分期望调用的内容可能是可调整的.例如,在Visual Studio中,链接器设置中有一个入口点名称的字段.