C++,SDL-2中出现未定义的引用WinMain@16

15

我一直遇到错误 undefined reference to WinMain@16。为了节省空间,这里是当前项目中的所有文件的链接。目前,它不应该做太多事情,只能创建一个窗口,在其中填充绿色,然后在角落画一个框,同时通过控制台跟踪我的鼠标位置。但是,它无法构建,我收到了上述错误。

我的链接器库包括:

  • glew32s
  • libSDL2main
  • mingw32
  • libSDL2
  • opengl32
  • glew32

我使用的是符合C++11 ISO C++语言标准的g++和Codeblocks 13.12。我的PC使用Windows 10,如果有相关的话。

我花了很长时间寻找解决方案,似乎每个人都有完全不同的解决方案,到目前为止,它们都没有对我起作用。几个例子包括:

  • 根据这个类似的问题,在我的链接库中添加SDL2_image。它给了我错误-lSDL2_image
  • 从头开始启动项目,以防我没有注意到的某个拼写错误是原因。(我得到了完全相同的错误)。
  • 将我的main函数更改为WinMain。我得到了相同的错误消息。
  • 添加Windows.h头文件。这没有什么显著的作用。
  • 各种所谓的“正确顺序”的链接器库。到目前为止,这些都似乎没有帮助。

我还应该指出,用户提供的答案,Cheers and hth. - Alf,在这里可能是我正在寻找的答案,但老实说,我无法完全理解我应该根据它做什么。

如果有任何相关的信息我忘记了,请告诉我,我会尽快补充。谢谢提前。


可能是 https://dev59.com/0Wcs5IYBdhLWcg3wym_D 的重复问题。 - πάντα ῥεῖ
1
在 main.cpp 的开头尝试使用 #undef main - Poriferous
2个回答

30

我认为你想要什么

#define SDL_MAIN_HANDLED
在您的主文件中,在该行之前,留下以下内容:
#include <SDL2/SDL.h>

解释:

在SDL / SDL2中,为了让某些类型应用的跨平台开发更加简单,SDL会创建一个自定义的应用程序“入口点”。也就是说,你的int main()函数不是实际的主函数。实际上,SDL头文件中定义了一个名为main的宏,这导致你的主函数被重命名为SDL_main或类似的名称。随后,在“SDL_main”库中定义了另一个真正的main函数,将成为应用程序的实际main函数。这个main函数只是以适合所在平台的方式获取命令行参数,并调用你的main函数(已重命名为SDL_main)。

在Windows系统上,对于作为控制台程序还是GUI程序启动应用程序还有一些不同之处,需要注意。

有时候你希望SDL为你处理这些事情,但如果你正在开发传统的控制台程序,通常你不需要这样做。因此,你可以通过向SDL传递SDL_MAIN_HANDLED宏来防止SDL进行这些操作。

#undef main 的方法也可以起到相同的作用,但不如上述方法好,因为通过这种方式,你告诉SDL实际发生了什么。而使用上述方法,SDL认为所有的处理都将被使用,并且你随后通过#undef来粗暴地禁用它们。

如果你想查看各种宏/平台检查的详细信息,可以查看SDL_main.h头文件。如果你想知道SDL主函数系统的好处,可以查看SDL文档。


2
这样就解决了错误。谢谢。如果您不介意我问一下,为什么/如何解决了这个问题? - The Orca

9
被接受答案中提出的解决方案(未定义 main ,定义 SDL_MAIN_HANDLED 等)偏离了SDL2的预期用法。这种方法是否可行是另一个问题,但我仍然更喜欢坚持使用预期的方法。
该错误意味着您没有链接正确的库或以错误的顺序链接它们。
您需要按照以下确切顺序: -lmingw32 -lSDL2main -lSDL2
这样做可能会将错误更改为 undefined reference to `SDL_main'。这意味着您使用的 main 签名与SDL所期望的不同。它必须是 int main(int,char **) int main(int,char * [])。允许添加参数名称,但您不能更改其他内容:即使您不使用它们,也必须具有参数。

2
谢谢,那个方法可行。这应该是被接受的答案。 - Peter Kofler
我不完全确定你所说的CMake将确定正确的标志是什么意思。当我在Linux上没有使用IDE进行编译时,只需链接SDL2而不链接mingw32SDL2main就可以正常工作。然而,当我在Windows上使用CLion(使用mingw gcc作为编译器)进行编译时,我必须先添加这两个标志。虽然我想我还没有在Linux上没有使用IDE的情况下测试过使用这两个标志进行编译。 - undefined
@JosieThompson 我不使用CMake,所以我不知道你需要为当前平台自动确定这些标志的确切步骤,但肯定有办法。即使使用pkg-config-lmingw32 -lSDL2main也会自动添加。 - undefined
1
@JosieThompson 找到了:https://github.com/libsdl-org/SDL/blob/SDL2/docs/README-cmake.md#including-sdl-in-your-project - undefined
哦,我明白了 - 似乎带有命名空间的目标会链接所需的库,而没有命名空间的目标则不会链接。 - undefined
显示剩余2条评论

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