如何链接外部DLL,更具体地说如何手动编译SDL?
最近,我停止使用IDE,以尝试更多地了解编程基础架构。我开始使用mingw的编译器(g ++。EXE
和gcc.exe
相应地编译C ++和C代码)和PowerShell的帮助。
这一切都很好,直到我想再次使用SDL进行项目,并且在手动链接中惨败。我想通过说我阅读了很多有关链接,.dll
文件,gcc
和编译器标志的信息,我正在努力理解编译器的工作方式。
我的基本理解是,当您要使用DLL时,您需要一个库文件来链接函数,变量等的名称。 > file,但是这个似乎并非总是如此,因为当我自己制作自己的dll(gcc -shared -o mydll.dll.dll.dll.o mydll.o
)时,我只有必须像So GCC Main.c -o Main -L一样链接它。 -l:mydll.dll
,没有库文件。
尽管我设法编译了SDL,也许我可能没有尝试过像GLFW甚至OpenGL这样的东西,但我会理解它,但是经过大量的阅读和尝试,我仍然没有成功。为了开始,我只关心在C中使用SDL编译一个小程序,我只会显示我的一种尝试。
步骤1
我从在这里。从X86_64-W64-MINGW32
文件夹中获取了内容,因为这是我正在使用的OS。从主文件夹中的bin文件夹中取出sdl2.dll
了解我在做什么)。然后,我删除了共享文件夹和bin文件夹,因为我认为我不需要它们。我留下了以下文件夹内容(在制作main.c
文件之后):
step 2
在main.c
文件中写下以下内容:
#include <stdio.h>
#include <SDL2/SDL.h>
int main(int argc, char *argv[]) {
if (!SDL_Init(SDL_INIT_EVERYTHING)) printf("SDL Error: %s\n", SDL_GetError());
SDL_Window *window = SDL_CreateWindow("test", 0, 0, 960, 540, SDL_RENDERER_ACCELERATED);
SDL_Delay(5000);
SDL_Quit();
return 0;
}
步骤3
尝试使用一个命令编译(跳过将所有内容转换为对象文件):
gcc main.c -o main -L lib -l:libSDL2.a -l:libSDL2main.a -I include
步骤4
收到此错误消息,这是我最远的我总是使用编译SDL或GLFW
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0xe): undefined reference to `SDL_Init'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x17): undefined reference to `SDL_GetError'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x5b): undefined reference to `SDL_CreateWindow'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x6a): undefined reference to `SDL_Delay'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x6f): undefined reference to `SDL_Quit'
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
Recently I stopped using IDEs in an attempt to learn more about the infrastructure of programming; I started compiling my C++ and C code with MinGW's compilers(g++.exe
and gcc.exe
accordingly) and the help of PowerShell.
This is all worked out well until I wanted to use SDL again for a project and failed miserably at manual linking. I want to preface this by saying that I've read a lot about linking, .dll
files, gcc
and compiler flags and I am struggling to understand the way the compiler works.
My basic understanding is that when you want to use a DLL you need a library file to link the names of the functions, variables, etc. from your header file with the location of those things in the binary .dll
file, but this seems to not be always the case, because, when I made my own DLL(gcc -shared -o mydll.dll mydll.o
) I only had to link it like so gcc main.c -o main -L . -l:mydll.dll
, no library file whatsoever.
I though that if I manage to compile SDL and maybe something I haven't tried like GLFW or even OpenGL I would understand it, but after a ton of reading and trying I still haven't succeeded to do so. And to start it small I only care about compiling a small program with SDL in C and I will only show one of my attempts to do so.
STEP 1
I got the development library for MinGW from here. Got the contents from the x86_64-w64-mingw32
folder as that is the OS I am using. Took out the SDL2.dll
from the bin folder in the main folder so it was where the executable would be.(I avoided folders for binaries, object files, source code and headers to keep things simple until I learned what I was doing). Then I removed the shared folder and the bin folder as I thought I didn't need them. I was left with the following folder contents(after making a main.c
file):
STEP 2
Wrote the following in the main.c
file:
#include <stdio.h>
#include <SDL2/SDL.h>
int main(int argc, char *argv[]) {
if (!SDL_Init(SDL_INIT_EVERYTHING)) printf("SDL Error: %s\n", SDL_GetError());
SDL_Window *window = SDL_CreateWindow("test", 0, 0, 960, 540, SDL_RENDERER_ACCELERATED);
SDL_Delay(5000);
SDL_Quit();
return 0;
}
STEP 3
Tried to compile with one command(skipping turning everything into an object file first):
gcc main.c -o main -L lib -l:libSDL2.a -l:libSDL2main.a -I include
STEP 4
Got this error message which is the furthest I've always gone with compiling SDL or GLFW
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0xe): undefined reference to `SDL_Init'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x17): undefined reference to `SDL_GetError'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x5b): undefined reference to `SDL_CreateWindow'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x6a): undefined reference to `SDL_Delay'
C:\Users\igyul\AppData\Local\Temp\cc4Vbdvm.o:main.c:(.text+0x6f): undefined reference to `SDL_Quit'
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,该解决方案可行,假设DLL应该是所需的位置,并且Windows/GCC知道它在哪里,
Heres 一个如此回答的问题,可以解决您的问题,以防GCC找到SDL2库(我更习惯与具有专用库路径的Linux一起使用)。您还将添加-lc:\ your_library_path到第二GCC命令,当您将DLL从图书馆目录中拉出时,
我已将dll撤出,我选择了您的代码并运行了它具有以下命令
,这是您的代码
,并且“只是工作”,那就是在我执行实际可执行文件之前,它给了我“ SDL错误”并停止了执行,但是上述答案是您的问题
Well this solution works assuming the dll is supposed to be where it needs to and windows/gcc knows where it is,
heres a so answered question that solves your issue in case gcc doesn't find the sdl2 library(im more used to work with Linux which has a dedicated library path) also you will prob add -LC:\your_library_path to the second gcc command, as you pulled the dll out of the library directory
I've took your code and ran it with the following commands
and here's your code
and it "just worked", well that is until i executed the actual executable, it gave me a "SDL Error" and stopped the execution, but the above answers your question