为什么SDL定义了main宏?

54

在设置SDL时遇到了一些麻烦,后来发现SDL定义了一个宏来替换主函数:

#define main SDL_main

// And then
extern C_LINKAGE int SDL_main(int argc, char *argv[]);

如果主函数没有定义argcargv参数,这也会导致编译错误。

只是看到这个宏就让我头疼... 为什么SDL需要重新定义main函数?经过更多搜索,我发现有些人会#undef main,并按照正常的方式使用。

那么问题来了: 为什么SDL需要重新定义main函数,它是做什么的?取消定义有副作用吗?

我注意到一件事情,就是SDL将标准输出和错误重定向到文件中(而我不想要这种行为),但是如果取消定义main函数,这种行为就会停止。


1
你可以禁用这个行为。 - Kotauskas
1
哎呀,这篇文章里有很多愤怒的情绪。这样做的主要原因是为了在Windows上抽象出不同的入口点(winmain)和其他平台上的传统入口点(int main)。它简化了许多本来需要ifdefs或单独的源文件的代码。这是一种方便机制,如果您选择的话也可以手动完成。 - Qix - MONICA WAS MISTREATED
2个回答

59
根据 SDL Windows FAQ ,即使你创建了一个Windows应用程序,你应该使用 main() 而不是 WinMain() ,因为SDL提供了一个版本的 WinMain() 在调用你的主要代码之前执行一些SDL初始化。如果出于某种原因需要使用 WinMain() ,请查看 src / main / win32 / SDL_main.c 中的SDL源代码以查看在 WinMain() 函数中需要进行哪种类型的初始化,以便SDL正常工作。

SDL需要初始化,因此它注入自己的 main 函数以在调用您的“main”函数之前运行其初始化,然后将其重命名为 SDL_main 以避免与实际的 main 函数发生冲突。如常见问题解答所述,您的 main 函数必须采用以下形式:

int main(int argc, char* argv[])

41
几乎每个库都需要初始化,但这看起来不是一个好的实践方法。无论如何还是给它+1(即点赞)。 - David Grayson
28
@DavidGrayson 的做法实在糟糕,尤其是如果你有两个库都这样做的话......非常麻烦。 - Captain Obvlious
2
我可以编写自己的main()实现,而不使用这个奇怪的SDL_main()函数吗?有一些东西(例如stdout重定向)被强制执行,而我并不想要它。 - Tibi
2
同意 David。这个宏是 C 技术。C++ 有很多更好的替代方案。 - MSalters
2
我不仅同意David关于这是一种糟糕的做法的看法,而且SDL有自己的SDL_init调用来进行初始化。就我所记得的,SDLmain中的初始化非常无用(如果我没记错的话,只是重定向控制台)。 - BlakBat
1
这是误导性的,因为我不得不将我的“main()”函数改为“WinMain()”,然后在“SDL_Main.h”中更改注入方式从“main”到“WinMain”(我包含它),以避免不得不“#define SDL_MAIN_HANDLED”(没有处理它)。否则编译器(MinGW + gcc 12)会抱怨缺少“WinMain()”。似乎SDL团队已经更新了,但并没有相应地更改文档。无论如何,这似乎使注入正常工作。 - Dominic Grenier

13

虽然我同意这是一种奇怪的做法,但在某些情况下,这是一个合理的解决方案,尽管它在很大程度上取决于平台。考虑到不同平台有不同的入口点。Windows通常是WinMain,Linux是main,与Android交互发生在Java中,WinRT使用C++/CX扩展等等。程序入口点和API可以非常特定于平台,而SDL试图为您省去处理这个问题的麻烦。如果您只针对Windows,并且SDL仅存在于此,以便为您节省使用WIN32 API的麻烦,那么您可能不需要它。但是,如果您超越了桌面,我认为您会发现它很有用。


3
“超越桌面” — 嘿!Linux和OsX也属于桌面操作系统。 - val is still with Monica
1
在任何MinGW工具链上,Windows通常是WinMain。您可以使用标准的C或C++ main,MinGW将会处理使其正常工作。 - Xeverous
@Xeverous;虽然这可能是真的,但是当使用SDL时,如果您按照文档进行注入,编译器仍会抱怨“Winmain()”。 - Dominic Grenier
@DominicGrenier 这只是一个奇怪的错误信息。如果添加mainWinMain(或正确链接SDL2main),它将消失。 - HolyBlackCat

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