如何在我的程序中正确使用 SDL2?
How do I use SDL2 in my programs correctly?
I want to make a game using SDL2, but I'm unable to compile and/or run my code, please help!
SDL2 是出了名的难以设置,它通常是有抱负的游戏开发人员首先尝试使用的库。
此 post 旨在作为设置 SDL2 常见问题的规范副本。
这个答案是关于 MinGW / GCC,而不是 Visual Studio。
此回答仅适用于Windows。
常见错误
常见错误有:
SDL.h: No such file or directory
(编译时)
- 各种
SDL_main
问题:“对SDL_main的未定义引用”、“SDL_main的冲突类型”或“参数数量与原型不匹配”等(当编译或链接)
undefined reference
到其他函数(链接时)
- DLL 问题:(当 运行ning 你的程序时)
'??.dll' was not found
procedure entry point ... could not be located in ...
,以及其他神秘的 DLL-related 错误
- 程序启动时似乎什么也没做
此列表按从坏到好排序。如果您更改某些内容并遇到不同的错误,请使用此列表来判断您是让事情变得更好还是更糟。
序言
0。不要听从坏建议。
某些资源会建议您执行 #define SDL_MAIN_HANDLED
或 #undef main
。不要盲目地遵循该建议,这不是 SDL2 的用途。
如果你每件事都做对了,就永远没有必要了。首先了解预期的方法。然后你可以研究它到底做了什么,并做出明智的决定。
1.弄清楚如何直接从控制台编译,您可以稍后开始使用 IDE and/or 构建系统。
如果您使用 IDE,我建议首先确保您能够直接从控制台编译您的程序,以排除任何 IDE 配置问题。弄清楚之后,您可以在 IDE.
中使用相同的编译器选项
这同样适用于构建系统,例如 CMake。
2。下载正确的 SDL2 文件。确保您拥有正确的文件。您需要来自 here.
的名为 SDL2-devel-2.0.x-mingw.tar.gz
的存档
将它解压到任何目录,最好是靠近源代码的地方。提取到编译器安装目录通常被认为是一种不好的做法(将它们复制到 C:\Windows
,这是一个糟糕的想法)。
3。了解 编译器标志 和 链接器标志 . 之间的区别 “标志”是您在构建时在命令行中指定的选项你的程序。当您使用单个命令时,例如g++ foo.cpp -o foo.exe
,你所有的标志都被添加到同一个地方(到这个单一的命令)。
但是当您分两步构建程序时,例如:
g++ foo.cpp -c -o foo.o
(编译中)
g++ foo.o -o foo.exe
(链接)
您必须知道要为这两个命令中的哪一个添加标志。这些分别是“编译器标志”和“链接器标志”。
大多数 IDEs 将要求您分别指定编译器和链接器标志,因此即使您使用单个命令 now,最好知道哪个标志去哪里.
除非另有说明,标志的顺序无关紧要。
SDL.h: No such file or directory
或与包含 SDL.h
或 SDL2/SDL.h
相关的任何类似错误。
您需要告诉您的编译器在哪里查找 SDL.h
。它在您下载的 SDL 文件中(请参阅序言)。
将 -Ipath
添加到您的编译器标志中,其中 path
是 SDL.h
所在的目录。
示例:-IC:/Users/HolyBlackCat/Downloads/SDL2-2.0.12/x86_64-w64-mingw32/include/SDL2
。相对路径也有效,例如-ISDL2-2.0.12/x86_64-w64-mingw32/include/SDL2
.
注意路径会根据你写的方式不同#include
:
- 如果您执行
#include <SDL.h>
,则路径应以 .../include/SDL2
结尾(如上)。这是推荐的方式。
- 如果你
#include <SDL2/SDL.h>
,那么路径应该以.../include
结束。
各种SDL_main
问题
您可能会遇到几个不同的错误,提到 SDL_main
,例如 undefined reference to SDL_main
,或 conflicting types for 'SDL_main'
,或 number of arguments doesn't match prototype
,等等
你需要有一个main
函数。您的 main
函数必须类似于 int main(int, char **)
。 不 int main()
和不 void main()
。这是 SDL2 的一个怪癖,与它做 #define main SDL_main
.
有关
允许添加参数名称(并且在 C 中是强制性的),例如int main(int argc, char **argv)
。第二个参数也可以写成 char *[]
或名称:char *argv[]
。不允许进行其他更改。
如果您的项目有多个源文件,请确保在定义 main
函数的文件中包含 SDL.h
,即使它不直接使用 SDL。
解决这个问题时尽量避免#define SDL_MAIN_HANDLED
或#undef main
,解释见序言。
undefined reference to
各种函数
错误消息会提到各种 SDL_...
函数,and/or WinMain
。如果它提到 SDL_main
,请参阅上面的“各种 SDL_main
问题”部分。
您需要添加以下链接器标志:-lmingw32 -lSDL2main -lSDL2 -Lpath
,其中 path
是 libSDL2.dll.a
和 libSDL2main.a
(您下载的)所在的目录。 -l...
标志的顺序很重要。他们一定出现在任何 .c
/.cpp
/.o
文件之后。
示例:-LC:/Users/HolyBlackCat/Desktop/SDL2-2.0.12/x86_64-w64-mingw32/lib
。相对路径也有效,例如-LSDL2-2.0.12/x86_64-w64-mingw32/lib
.
当您使用 -l???
时,链接器将查找名为 lib???.dll.a
或 lib???.a
的文件(以及一些其他变体),这就是为什么我们需要传递位置那些文件。 libmingw32.a
(对应于 -lmingw32
)随您的编译器一起提供,因此它已经知道在哪里可以找到它。
我添加了所有这些标志,但没有任何改变:
您可能使用了错误的 SDL .a
文件。您下载的存档包含两组文件:i686-w64-mingw32
(32 位)和 x86_64-w64-mingw32
(64 位)。您必须使用与您的编译器匹配的文件,它也可以是 32 位或 64 位的。
打印 (8*sizeof(void*))
以查看您的编译器是 32 位还是 64 位。
即使您认为自己使用了正确的文件,也请尝试其他文件以确保安全。
一些 MinGW 版本可以使用 -m32
和 -m64
标志(将它们添加到编译器和链接器标志)在 32 位和 64 位模式之间切换。
我得到undefined reference
一个特定的函数:
• undefined reference to WinMain
仅
有几种可能性,所有这些都在上一节中介绍过:
- 您忘记了
-lmingw32
and/or -lSDL2main
链接器标志。
您必须按照以下确切顺序使用以下链接器标志,after
任何 .c
/.cpp
/.o
文件:-lmingw32 -lSDL2main -lSDL2
- 您使用的
libSDL2main.a
文件与您的编译器不匹配(32 位文件与 64 位编译器,反之亦然)。
解决这个问题时尽量避免#define SDL_MAIN_HANDLED
或#undef main
,解释见序言。
• undefined reference to SDL_main
仅
请参阅上面的“各种 SDL_main
问题”部分。
当我尝试 运行 我的应用程序时没有任何反应
假设您尝试 运行 您的应用程序,但没有任何反应。即使您尝试打印 main()
开头的内容,也不会打印出来。
Windows 有一个坏习惯,当程序从控制台启动时不显示一些 DLL-related 错误。
如果您是从控制台(或从 IDE)运行安装您的应用程序,请尝试 double-clicking 资源管理器中的 EXE。您现在很可能会看到一些 DLL-related 错误;然后参考下一节。
??.dll
未找到
复制错误消息中提到的 .dll
,并将其放在您的 .exe
旁边。
如果 DLL 被称为 SDL2.dll
,那么它就在您下载的 SDL 文件中(参见序言)。请注意,有两种不同的 SDL2.dll
:一种是 32 位的(在 i686-w64-mingw32
目录中),另一种是 64 位的(在 x86_64-w64-mingw32
中)。选对一个,如果有必要,两个都试试。
任何其他 DLL 将在编译器的 bin
目录中(gcc.exe
所在的目录)。
您可能需要重复此过程 3-4 次,这是正常的。
有关自动确定所需 DLL 的方法,请参阅下一节。
procedure entry point ... could not be located in ...
和其他神秘的 DLL 错误
您的程序需要几个 .dll
到 运行,它发现一个错误的版本,是您安装的其他程序遗留下来的。
它在几个不同的地方寻找 DLL,但带有 .exe
的目录具有最高优先级。
您应该将您的程序使用的所有 DLL(除了系统的)复制到您的 .exe
所在的目录中。
获得所需 DLL 列表的可靠方法是盲目地复制一堆 DLL,然后删除那些不需要的:
复制SDL2.dll
。它在您下载的 SDL 文件中(请参阅序言)。请注意,有两种不同的 SDL2.dll
:一种是 32 位的(在 i686-w64-mingw32
目录中),另一种是 64 位的(在 x86_64-w64-mingw32
中)。选对一个,如果有必要,两个都试试。
从编译器的 bin
目录(gcc.exe
所在的目录)复制所有 DLL。
现在您的程序应该 运行,但我们还没有完成。
下载 NTLDD(或显示已用 DLL 列表的其他程序)。 运行 ntldd -R your_program.exe
.
输出中提到的任何 not 的 DLL 都应该从当前目录中删除。您的程序会使用剩下的所有内容。
我最终得到了以下 DLL,期待类似的东西:SDL2.dll
、libgcc_s_seh-1.dll
、libstdc++-6.dll
(仅限 C++)、libwinpthread-1.dll
.
我可以在不复制过多的情况下确定需要的DLL吗?
是的,但不太可靠。
您的程序按以下顺序在以下位置搜索 DLL:
- 你的
.exe
所在的目录。
C:\Windows
,包括它的一些子目录。
- PATH中列出的目录。
假设您(或某些卡顿安装程序)没有将任何自定义 DLL 放入 C:\Windows
,添加您的ompiler 的 bin
目录到 PATH(最好是第一个条目)并且将 SDL2.dll
放在与 .exe
相同的目录中或放入 PATH 中的某个目录应该足以让您的程序工作。
如果可行,您可以 运行 ntldd
无需事先复制任何 DLL,只复制必要的。此时您想要完全复制它们的原因(因为您的应用程序已经可以运行)是为了能够将其分发给其他人,而无需他们为其 DLL 安装编译器。跳过位于编译器 bin
目录之外的所有 DLL(SDL2.dll
除外)。
请注意 C:\Windows
中存在奇怪的 DLL 的可能性是真实存在的。例如。 Wine 倾向于将 OpenAL32.dll
放入 C:\Windows
,因此如果您在 Wine 上使用 OpenAL 尝试此过程,它 将 失败。如果你正在制作一个自动 运行s ntldd
的 sciprt,更喜欢复制 DLL(或者至少对它们进行符号链接 - 我听说 MSYS2 可以模拟 Windows 上的符号链接?)。
我可以制作一个不依赖于任何 DLL 的 EXE 吗?
可以通过使用 -static
链接器标志来创建不依赖于任何 (non-system) .dll
的 .exe
,这称为“静态链接”。很少这样做,如果您正确执行了上述步骤,则不需要这样做。这需要一些额外的链接器标志;它们在 SDL 附带的文件 ??-w64-mingw32/lib/pkgconfig/sdl2.pc
中的 Libs.private
部分中列出。请注意,有两个文件,分别用于 x32 和 x64。
如何将我的应用分发给其他人?
按照标题为 procedure entry point ... could not be located in ...
的上一节中的步骤进行操作。
更明智的选择?
有MSYS2.
它有一个包管理器,可以让你下载预构建的库,作为奖励,还有一个新版本的编译器。
从包管理器安装 SDL2。使用名为 pkg-config
的工具(也来自包管理器)自动确定所有必要的标志(pkg-config --cflags SDL2
用于编译器标志,pkg-config --libs SDL2
用于链接器标志)。
这与您在 Linux 上的体验相同(可能除了一些 DLL 管理麻烦)。
奖金 - 其他问题
问:我的程序总是在我运行时打开一个控制台window,如何隐藏它?
- A: 添加
-mwindows
到链接器标志。
问:我收到 错误 'SDL_VideoMode' wasn't declared in this scope
。
- A:
SDL_VideoMode
来自SDL1.2,它不是较新的SDL2 的一部分。您的代码是为过时版本的 SDL 编写的。查找专门针对 SDL2 的更好的教程。
问:我的程序有默认文件图标,但我想要一个自定义图标。
答:您的图标必须是.ico
格式。如果您的图形编辑器不支持它,请制作一系列常见尺寸的 .png
(例如 16x16、32x32、48x48、64x64),然后使用 [=164= 将它们转换为单个 .ico
]:magick *.png result.ico
(或使用 convert
而不是 magick
)。
创建一个扩展名为 .rc
的文件(比如 icon.rc
),内容如下 MyIconName ICON "icon.ico"
(其中 MyIconName
是任意名称,"icon.ico"
是图标的路径)。使用 windres -O res -i icon.rc -o icon.o
将文件转换为 .o
(windres
程序随编译器一起提供)。链接时指定生成的 .o
文件,例如g++ foo.cpp icon.o -o foo.exe
.
SDL2 的最新版本有一个很好的 属性 使用与 window 图标相同的图标,因此您不必使用 SDL_SetWindowIcon
.
在 Mac 这是我为 XCode 遵循的(必须安装 g++):
sdl 链接:
g++ main.cpp -o main $(sdl2-config --cflags --libs)
XCODE 项目步骤:
打开终端应用程序 (macOS)
构建设置(select 'all' 和 'combined' 搜索栏输入:“搜索”)
单击“header 搜索路径(单击右侧)
添加:/usr/local/include
构建阶段 --> LINK 二进制库(点击加号)
输入SDL
--> 点击“添加其他”
按:命令+SHIFT+g(带搜索栏)
输入:usr/local/Cellar
导航到:SDL2 -->2.0.8 -->lib --> libSDL2-2.2.0.dylib(确保不是快捷方式)
Visual Studio的解决方案:
为什么不使用包管理器?我使用 vcpkg,它使使用 3rd 方库变得非常容易。获取 vcpkg 源,并将其解压缩到安全的地方,例如 C:/
,然后 运行 其 bootstrap 脚本 bootstrap-vcpkg.bat
,这将生成 vcpkg
可执行文件。然后 运行 vcpkg integrate install
使使用 vcpkg 安装的库在 Visual Studio.
中可用
搜索您需要的图书馆:
vcpkg search sdl
imgui[sdl2-binding] Make available SDL2 binding
libwebp[vwebp-sdl] Build the vwebp viewer tool.
magnum[sdl2application] Sdl2Application library
sdl1 1.2.15#12 Simple DirectMedia Layer is a cross-platform development library designed to p...
sdl1-net 1.2.8-3 Networking library for SDL
sdl2 2.0.12-1 Simple DirectMedia Layer is a cross-platform
...
安装:vcpkg install sdl2
.
现在您只需要包含 SDL2 headers,一切都会开箱即用。该库将自动链接。
您可以了解有关 vcpkg 的更多信息here。
I want to make a game using SDL2, but I'm unable to compile and/or run my code, please help!
SDL2 是出了名的难以设置,它通常是有抱负的游戏开发人员首先尝试使用的库。
此 post 旨在作为设置 SDL2 常见问题的规范副本。
这个答案是关于 MinGW / GCC,而不是 Visual Studio。
此回答仅适用于Windows。
常见错误
常见错误有:
SDL.h: No such file or directory
(编译时)- 各种
SDL_main
问题:“对SDL_main的未定义引用”、“SDL_main的冲突类型”或“参数数量与原型不匹配”等(当编译或链接) undefined reference
到其他函数(链接时)- DLL 问题:(当 运行ning 你的程序时)
'??.dll' was not found
procedure entry point ... could not be located in ...
,以及其他神秘的 DLL-related 错误- 程序启动时似乎什么也没做
此列表按从坏到好排序。如果您更改某些内容并遇到不同的错误,请使用此列表来判断您是让事情变得更好还是更糟。
序言
0。不要听从坏建议。
某些资源会建议您执行 #define SDL_MAIN_HANDLED
或 #undef main
。不要盲目地遵循该建议,这不是 SDL2 的用途。
如果你每件事都做对了,就永远没有必要了。首先了解预期的方法。然后你可以研究它到底做了什么,并做出明智的决定。
1.弄清楚如何直接从控制台编译,您可以稍后开始使用 IDE and/or 构建系统。 如果您使用 IDE,我建议首先确保您能够直接从控制台编译您的程序,以排除任何 IDE 配置问题。弄清楚之后,您可以在 IDE.
中使用相同的编译器选项这同样适用于构建系统,例如 CMake。
2。下载正确的 SDL2 文件。确保您拥有正确的文件。您需要来自 here.
的名为SDL2-devel-2.0.x-mingw.tar.gz
的存档
将它解压到任何目录,最好是靠近源代码的地方。提取到编译器安装目录通常被认为是一种不好的做法(将它们复制到 C:\Windows
,这是一个糟糕的想法)。
3。了解 编译器标志 和 链接器标志 . 之间的区别 “标志”是您在构建时在命令行中指定的选项你的程序。当您使用单个命令时,例如g++ foo.cpp -o foo.exe
,你所有的标志都被添加到同一个地方(到这个单一的命令)。
但是当您分两步构建程序时,例如:
g++ foo.cpp -c -o foo.o
(编译中)g++ foo.o -o foo.exe
(链接)
您必须知道要为这两个命令中的哪一个添加标志。这些分别是“编译器标志”和“链接器标志”。
大多数 IDEs 将要求您分别指定编译器和链接器标志,因此即使您使用单个命令 now,最好知道哪个标志去哪里.
除非另有说明,标志的顺序无关紧要。
SDL.h: No such file or directory
或与包含 SDL.h
或 SDL2/SDL.h
相关的任何类似错误。
您需要告诉您的编译器在哪里查找 SDL.h
。它在您下载的 SDL 文件中(请参阅序言)。
将 -Ipath
添加到您的编译器标志中,其中 path
是 SDL.h
所在的目录。
示例:-IC:/Users/HolyBlackCat/Downloads/SDL2-2.0.12/x86_64-w64-mingw32/include/SDL2
。相对路径也有效,例如-ISDL2-2.0.12/x86_64-w64-mingw32/include/SDL2
.
注意路径会根据你写的方式不同#include
:
- 如果您执行
#include <SDL.h>
,则路径应以.../include/SDL2
结尾(如上)。这是推荐的方式。 - 如果你
#include <SDL2/SDL.h>
,那么路径应该以.../include
结束。
各种SDL_main
问题
您可能会遇到几个不同的错误,提到 SDL_main
,例如 undefined reference to SDL_main
,或 conflicting types for 'SDL_main'
,或 number of arguments doesn't match prototype
,等等
你需要有一个main
函数。您的 main
函数必须类似于 int main(int, char **)
。 不 int main()
和不 void main()
。这是 SDL2 的一个怪癖,与它做 #define main SDL_main
.
允许添加参数名称(并且在 C 中是强制性的),例如int main(int argc, char **argv)
。第二个参数也可以写成 char *[]
或名称:char *argv[]
。不允许进行其他更改。
如果您的项目有多个源文件,请确保在定义 main
函数的文件中包含 SDL.h
,即使它不直接使用 SDL。
解决这个问题时尽量避免#define SDL_MAIN_HANDLED
或#undef main
,解释见序言。
undefined reference to
各种函数
错误消息会提到各种 SDL_...
函数,and/or WinMain
。如果它提到 SDL_main
,请参阅上面的“各种 SDL_main
问题”部分。
您需要添加以下链接器标志:-lmingw32 -lSDL2main -lSDL2 -Lpath
,其中 path
是 libSDL2.dll.a
和 libSDL2main.a
(您下载的)所在的目录。 -l...
标志的顺序很重要。他们一定出现在任何 .c
/.cpp
/.o
文件之后。
示例:-LC:/Users/HolyBlackCat/Desktop/SDL2-2.0.12/x86_64-w64-mingw32/lib
。相对路径也有效,例如-LSDL2-2.0.12/x86_64-w64-mingw32/lib
.
当您使用 -l???
时,链接器将查找名为 lib???.dll.a
或 lib???.a
的文件(以及一些其他变体),这就是为什么我们需要传递位置那些文件。 libmingw32.a
(对应于 -lmingw32
)随您的编译器一起提供,因此它已经知道在哪里可以找到它。
我添加了所有这些标志,但没有任何改变:
您可能使用了错误的 SDL .a
文件。您下载的存档包含两组文件:i686-w64-mingw32
(32 位)和 x86_64-w64-mingw32
(64 位)。您必须使用与您的编译器匹配的文件,它也可以是 32 位或 64 位的。
打印 (8*sizeof(void*))
以查看您的编译器是 32 位还是 64 位。
即使您认为自己使用了正确的文件,也请尝试其他文件以确保安全。
一些 MinGW 版本可以使用 -m32
和 -m64
标志(将它们添加到编译器和链接器标志)在 32 位和 64 位模式之间切换。
我得到undefined reference
一个特定的函数:
• undefined reference to WinMain
仅
有几种可能性,所有这些都在上一节中介绍过:
- 您忘记了
-lmingw32
and/or-lSDL2main
链接器标志。
您必须按照以下确切顺序使用以下链接器标志,after 任何.c
/.cpp
/.o
文件:-lmingw32 -lSDL2main -lSDL2
- 您使用的
libSDL2main.a
文件与您的编译器不匹配(32 位文件与 64 位编译器,反之亦然)。
解决这个问题时尽量避免#define SDL_MAIN_HANDLED
或#undef main
,解释见序言。
• undefined reference to SDL_main
仅
请参阅上面的“各种 SDL_main
问题”部分。
当我尝试 运行 我的应用程序时没有任何反应
假设您尝试 运行 您的应用程序,但没有任何反应。即使您尝试打印 main()
开头的内容,也不会打印出来。
Windows 有一个坏习惯,当程序从控制台启动时不显示一些 DLL-related 错误。
如果您是从控制台(或从 IDE)运行安装您的应用程序,请尝试 double-clicking 资源管理器中的 EXE。您现在很可能会看到一些 DLL-related 错误;然后参考下一节。
??.dll
未找到
复制错误消息中提到的 .dll
,并将其放在您的 .exe
旁边。
如果 DLL 被称为 SDL2.dll
,那么它就在您下载的 SDL 文件中(参见序言)。请注意,有两种不同的 SDL2.dll
:一种是 32 位的(在 i686-w64-mingw32
目录中),另一种是 64 位的(在 x86_64-w64-mingw32
中)。选对一个,如果有必要,两个都试试。
任何其他 DLL 将在编译器的 bin
目录中(gcc.exe
所在的目录)。
您可能需要重复此过程 3-4 次,这是正常的。
有关自动确定所需 DLL 的方法,请参阅下一节。
procedure entry point ... could not be located in ...
和其他神秘的 DLL 错误
您的程序需要几个 .dll
到 运行,它发现一个错误的版本,是您安装的其他程序遗留下来的。
它在几个不同的地方寻找 DLL,但带有 .exe
的目录具有最高优先级。
您应该将您的程序使用的所有 DLL(除了系统的)复制到您的 .exe
所在的目录中。
获得所需 DLL 列表的可靠方法是盲目地复制一堆 DLL,然后删除那些不需要的:
复制
SDL2.dll
。它在您下载的 SDL 文件中(请参阅序言)。请注意,有两种不同的SDL2.dll
:一种是 32 位的(在i686-w64-mingw32
目录中),另一种是 64 位的(在x86_64-w64-mingw32
中)。选对一个,如果有必要,两个都试试。从编译器的
bin
目录(gcc.exe
所在的目录)复制所有 DLL。现在您的程序应该 运行,但我们还没有完成。
下载 NTLDD(或显示已用 DLL 列表的其他程序)。 运行
ntldd -R your_program.exe
.输出中提到的任何 not 的 DLL 都应该从当前目录中删除。您的程序会使用剩下的所有内容。
我最终得到了以下 DLL,期待类似的东西:SDL2.dll
、libgcc_s_seh-1.dll
、libstdc++-6.dll
(仅限 C++)、libwinpthread-1.dll
.
我可以在不复制过多的情况下确定需要的DLL吗?
是的,但不太可靠。
您的程序按以下顺序在以下位置搜索 DLL:
- 你的
.exe
所在的目录。 C:\Windows
,包括它的一些子目录。- PATH中列出的目录。
假设您(或某些卡顿安装程序)没有将任何自定义 DLL 放入 C:\Windows
,添加您的ompiler 的 bin
目录到 PATH(最好是第一个条目)并且将 SDL2.dll
放在与 .exe
相同的目录中或放入 PATH 中的某个目录应该足以让您的程序工作。
如果可行,您可以 运行 ntldd
无需事先复制任何 DLL,只复制必要的。此时您想要完全复制它们的原因(因为您的应用程序已经可以运行)是为了能够将其分发给其他人,而无需他们为其 DLL 安装编译器。跳过位于编译器 bin
目录之外的所有 DLL(SDL2.dll
除外)。
请注意 C:\Windows
中存在奇怪的 DLL 的可能性是真实存在的。例如。 Wine 倾向于将 OpenAL32.dll
放入 C:\Windows
,因此如果您在 Wine 上使用 OpenAL 尝试此过程,它 将 失败。如果你正在制作一个自动 运行s ntldd
的 sciprt,更喜欢复制 DLL(或者至少对它们进行符号链接 - 我听说 MSYS2 可以模拟 Windows 上的符号链接?)。
我可以制作一个不依赖于任何 DLL 的 EXE 吗?
可以通过使用 -static
链接器标志来创建不依赖于任何 (non-system) .dll
的 .exe
,这称为“静态链接”。很少这样做,如果您正确执行了上述步骤,则不需要这样做。这需要一些额外的链接器标志;它们在 SDL 附带的文件 ??-w64-mingw32/lib/pkgconfig/sdl2.pc
中的 Libs.private
部分中列出。请注意,有两个文件,分别用于 x32 和 x64。
如何将我的应用分发给其他人?
按照标题为 procedure entry point ... could not be located in ...
的上一节中的步骤进行操作。
更明智的选择?
有MSYS2.
它有一个包管理器,可以让你下载预构建的库,作为奖励,还有一个新版本的编译器。
从包管理器安装 SDL2。使用名为 pkg-config
的工具(也来自包管理器)自动确定所有必要的标志(pkg-config --cflags SDL2
用于编译器标志,pkg-config --libs SDL2
用于链接器标志)。
这与您在 Linux 上的体验相同(可能除了一些 DLL 管理麻烦)。
奖金 - 其他问题
问:我的程序总是在我运行时打开一个控制台window,如何隐藏它?
- A: 添加
-mwindows
到链接器标志。
- A: 添加
问:我收到 错误
'SDL_VideoMode' wasn't declared in this scope
。- A:
SDL_VideoMode
来自SDL1.2,它不是较新的SDL2 的一部分。您的代码是为过时版本的 SDL 编写的。查找专门针对 SDL2 的更好的教程。
- A:
问:我的程序有默认文件图标,但我想要一个自定义图标。
答:您的图标必须是
.ico
格式。如果您的图形编辑器不支持它,请制作一系列常见尺寸的.png
(例如 16x16、32x32、48x48、64x64),然后使用 [=164= 将它们转换为单个.ico
]:magick *.png result.ico
(或使用convert
而不是magick
)。创建一个扩展名为
.rc
的文件(比如icon.rc
),内容如下MyIconName ICON "icon.ico"
(其中MyIconName
是任意名称,"icon.ico"
是图标的路径)。使用windres -O res -i icon.rc -o icon.o
将文件转换为.o
(windres
程序随编译器一起提供)。链接时指定生成的.o
文件,例如g++ foo.cpp icon.o -o foo.exe
.SDL2 的最新版本有一个很好的 属性 使用与 window 图标相同的图标,因此您不必使用
SDL_SetWindowIcon
.
在 Mac 这是我为 XCode 遵循的(必须安装 g++):
sdl 链接:
g++ main.cpp -o main $(sdl2-config --cflags --libs)
XCODE 项目步骤:
打开终端应用程序 (macOS)
构建设置(select 'all' 和 'combined' 搜索栏输入:“搜索”)
单击“header 搜索路径(单击右侧)
添加:
/usr/local/include
构建阶段 --> LINK 二进制库(点击加号)
输入
SDL
--> 点击“添加其他”按:命令+SHIFT+g(带搜索栏)
输入:
usr/local/Cellar
导航到:SDL2 -->2.0.8 -->lib --> libSDL2-2.2.0.dylib(确保不是快捷方式)
Visual Studio的解决方案:
为什么不使用包管理器?我使用 vcpkg,它使使用 3rd 方库变得非常容易。获取 vcpkg 源,并将其解压缩到安全的地方,例如 C:/
,然后 运行 其 bootstrap 脚本 bootstrap-vcpkg.bat
,这将生成 vcpkg
可执行文件。然后 运行 vcpkg integrate install
使使用 vcpkg 安装的库在 Visual Studio.
搜索您需要的图书馆:
vcpkg search sdl
imgui[sdl2-binding] Make available SDL2 binding
libwebp[vwebp-sdl] Build the vwebp viewer tool.
magnum[sdl2application] Sdl2Application library
sdl1 1.2.15#12 Simple DirectMedia Layer is a cross-platform development library designed to p...
sdl1-net 1.2.8-3 Networking library for SDL
sdl2 2.0.12-1 Simple DirectMedia Layer is a cross-platform
...
安装:vcpkg install sdl2
.
现在您只需要包含 SDL2 headers,一切都会开箱即用。该库将自动链接。
您可以了解有关 vcpkg 的更多信息here。