更改入口点(main()函数)的目的是什么?

3

请看下面这段来自《OpenGL超级经验法则》第7版的main.cpp代码:

#include "sb7.h"

class my_application : public sb7::application
{
    void render(double currentTime)
    {
        static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
        glClearBufferfv(GL_COLOR, 0, red);
    }
};

DECLARE_MAIN(my_application);

sb7.h 中,关于 DECLARE_MAIN() 的相关代码如下:
#if defined _WIN32
#define DECLARE_MAIN(a)                             \
sb7::application *app = 0;                          \
int CALLBACK WinMain(HINSTANCE hInstance,           \
                     HINSTANCE hPrevInstance,       \
                     LPSTR lpCmdLine,               \
                     int nCmdShow)                  \
{                                                   \
    a *app = new a;                                 \
    app->run(app);                                  \
    delete app;                                     \
    return 0;                                       \
}
#elif defined _LINUX || defined __APPLE__
#define DECLARE_MAIN(a)                             \
int main(int argc, const char ** argv)              \
{                                                   \
    a *app = new a;                                 \
    app->run(app);                                  \
    delete app;                                     \
    return 0;                                       \
}
#else
#error Undefined platform!
#endif

使用这种不寻常的方法有什么好处?代码结构的可读性受到了威胁,但我猜想背后肯定有一定的用意。请注意,作者使用第三方glfw来处理窗口和用户输入,例如键盘和鼠标输入。我不明白他们为什么需要使用“CALLBACK WinMain()”,我知道它仅与Windows操作系统相关。说实话,看到不同的方法很好。

1
我不确定我理解这个问题。在 _WIN32 上的入口点是 WinMain,而在大多数其他环境中的入口点是 main - Eljay
目的是使真实代码在不同平台之间看起来一致。Windows(WinMain)和Linux(main)之间的差异在DECLARE_MAIN中被抽象化。在Windows下,WinMain是应用程序的默认入口点,如此文档所述:https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-point。 - dxiv
@dxiv,你的意思是说如果我在Visual Studio中将main()用作普通的C++项目,它会被内部转换,以便入口点为WinMain?! - CroCo
@Croco 这取决于编译器和链接器,它们的设置以及应用程序是否使用 CRT。例如,在 Windows 中使用 Visual C++ 构建的默认控制台应用程序将具有 mainCRTStartup 的入口点。但这在 CRT 代码中是“隐藏”的,您只会看到熟悉的 main - dxiv
书中的好处在于简化了书本,通过假设所有程序都使用DECLARE_MAIN()宏。该宏(有条件地)使用不同的入口点,因此呈现的代码示例将适用于Windows、Linux和其他操作系统,这些操作系统都使用不同的入口点来进行基于GUI的程序。由于样板代码不需要在每个代码示例中重复,因此该书更短且更易于编写。打印也会消耗更少的纸张。如果读者为程序入口点编写了不同的代码,则如果代码示例无法正常工作,他们不能责怪书的作者和出版商。 - Peter
显示剩余5条评论
2个回答

0

WinMain 用于 Windows API(如 GUI 等)。main 用于终端/控制台应用程序。它的编写方式是为了使 main 声明在所有平台上都是正常的。我进行了一些调查,发现 WinMain 是为了在 Windows 上移除控制台。请参见此处


你没有理解我的观点。作者使用第三方库GLFW来处理GUI,我不认为WinMain有任何意义。 - CroCo
@CroCo -- 这很奇怪...但是如果你看顶部,这一行:sb7::application *app = 0; 只适用于Windows。 - xilpex

-1

在Windows上,WinMain是GUI应用程序的非标准入口点。因此,代码反映了这一点。该代码仅适用于Windows和Linux/Apple操作系统。

#if defined _WIN32
//...
#elif defined _LINUX || defined __APPLE__
//...
#else
#error Undefined platform!
#endif

2
我认为你在中间漏掉了elif linux。 - pm100

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接