WINMAIN和C ++中的main()(扩展)

时间:2012-12-14 01:58:51

标签: c++ windows main winmain

是的,我看过这篇文章:Difference between WinMain,main and DllMain in C++

我现在知道WINMAIN用于窗口应用程序,main()用于控制台。但阅读这篇文章并没有真正告诉我为什么到底有什么区别。

我的意思是将不同的主电源功能分开到程序的开头是什么意思?是因为性能问题?或者它是什么?

6 个答案:

答案 0 :(得分:8)

根据@RaymondChen

The name WinMain is just a convention

  

虽然在Platform SDK中记录了WinMain函数,但它是   不是平台的一部分。相反,WinMain是传统的   用户提供的Windows程序入口点的名称。

     

真正的入口点在C运行时库中,它初始化   运行时,运行全局构造函数,然后调用WinMain   函数(如果您更喜欢Unicode入口点,则为wWinMain)。

DllMain和WinMain的原型本身不同。 WinMain接受命令行参数,而另一个讨论它是如何附加到进程的。

根据MSDN documentation

默认情况下,起始地址是C运行时库中的函数名称。链接器根据程序的属性选择它,如下表所示。

  • mainCRTStartup(或wmainCRTStartup)使用的应用程序 /SUBSYSTEM:CONSOLE;调用main(或wmain

  • WinMainCRTStartup(或wWinMainCRTStartup)使用的应用程序 /SUBSYSTEM:WINDOWS;调用WinMain(或wWinMain),必须是。{ 使用__stdcall

  • 定义
  • _DllMainCRTStartup一个DLL;调用DllMain,必须使用__stdcall进行定义(如果存在)

答案 1 :(得分:2)

标准C程序在启动时通过命令行传递2个参数:

int main( int argc, char** argv ) ;
  • char** argv是一个字符串数组(char*
  • int argc是argv
  • char*的数量

程序员必须为windows程序编写的引导函数WinMain略有不同。 WinMain接受Win O / S在启动时传递给程序的4个参数:

int WINAPI WinMain( HINSTANCE hInstance,    // HANDLE TO AN INSTANCE.  This is the "handle" to YOUR PROGRAM ITSELF.
                    HINSTANCE hPrevInstance,// USELESS on modern windows (totally ignore hPrevInstance)
                    LPSTR szCmdLine,        // Command line arguments.  similar to argv in standard C programs
                    int iCmdShow )          // Start window maximized, minimized, etc.

请参阅我的文章How to create a basic window in C了解更多

答案 2 :(得分:1)

我模糊地回忆一下Windows程序有main()功能的地方。它只是隐藏在某个地方的标题或库中。我相信这个main()函数会初始化WinMain()所需的所有变量,然后调用它。

当然,我是一个WinAPI菜鸟,所以我希望那些知识渊博的人会在我错的时候纠正我。

答案 3 :(得分:0)

我有一个使用_tWinMain和Configuration Properties.Linker.System.Subsystem:Windows(/ SUBSYSTEM:WINDOWS)的exe。后来我希望它支持cmdline args并打印到控制台,所以我添加了:

// We need to printf to stdout and we don't have one, so get one
AllocConsole();
// Redirect pre-opened STDOUT to the console
freopen_s((FILE **)stdout, "CONOUT$", "w", stdout);

,但这只能通过在另一个已消失的控制台窗口中进行打印来实现,因此没有什么用处。下面是我将其更改为与控制台(/ SUBSYSTEM:CONSOLE)一起使用的方式,如果需要的话,可以来回操作。

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  UNREFERENCED_PARAMETER(argc);
  UNREFERENCED_PARAMETER(argv);
  UNREFERENCED_PARAMETER(envp);
  return (_tWinMain(NULL, NULL, ::GetCommandLineW(), 0));
}

答案 4 :(得分:0)

Main vs WinMain

正如我从许多链接中读到的:

WinMain()是任何Windows应用程序的C入口点功能。像具有DOS/console功能作为main()入口点的普通基于C的应用程序一样,在Windows中,我们改为使用WinMain()WinMain()是一个在创建进程时由系统调用的函数。

第一个参数是当前进程的实例句柄。

下一个是前一个实例。

命令行参数作为下一个参数。

最后,shell传递了主窗口的显示/显示属性。

注意:WinMain返回的成功为零,错误为非零。

答案 5 :(得分:0)

Windows CRT公开了5个符号maincrtstartup,wmainCRTStartup,wWinMainCRTStartup,_DllMainCRTStartup,WinMainCRTStartup

enter image description here

如果未指定/ DLL或/ SUBSYSTEM选项,则MSVC链接器将根据定义了main还是WinMain选择一个子系统和入口点。因此,假定链接器根据符号表中是否存在main,WinMain或DllMain来使这5个功能之一成为入口地址。这些功能由gcc通过crt0.o静态链接。

MainCRTStartup将调用max /访问PEB以获取标准输入/输出句柄和命令行参数。也称为df2gr = df2.groupby(level=0) df2['last_2x'] = df2gr.cummax()\ .assign(l=df2gr.max().shift() .loc[df2.index.get_level_values(0)] .to_numpy())\ .max(axis=1, skipna=False) print (df2) A last_2x 2000-01-01 07:59:57 2000-01-01 08:00:00 4.0 NaN 2000-01-01 08:00:01 4.0 NaN 2000-01-01 08:00:02 2000-01-01 08:00:03 8.0 8.0 2000-01-01 08:00:04 15.0 15.0 2000-01-01 08:00:05 15.0 15.0 2000-01-01 08:00:06 15.0 15.0 2000-01-01 08:00:07 2000-01-01 08:00:09 14.0 15.0 2000-01-01 08:00:10 17.0 17.0 2000-01-01 08:00:11 17.0 17.0 2000-01-01 08:00:12 2000-01-01 08:00:12 20.0 20.0 2000-01-01 08:00:15 20.0 20.0 2000-01-01 08:00:16 20.0 20.0 2000-01-01 08:00:17 2000-01-01 08:00:18 5.0 20.0 2000-01-01 08:00:19 15.0 20.0 2000-01-01 08:00:20 15.0 20.0 2000-01-01 08:00:22 2000-01-01 08:00:22 10.0 15.0 2000-01-01 08:00:23 13.0 15.0 2000-01-01 08:00:24 20.0 20.0 2000-01-01 08:00:25 20.0 20.0 2000-01-01 08:00:26 20.0 20.0 2000-01-01 08:00:27 2000-01-01 08:00:27 10.0 20.0 2000-01-01 08:00:28 11.0 20.0 GetStartupInfo()。在调用集合_init term()例程之后,将main的返回值传递给_init_atexit()