为什么只为某些库向编译器提供我正在使用的* .lib文件?

时间:2019-06-10 00:26:29

标签: c windows compilation linker cl

我一直在关注一些教程,这些教程使用一些C库在Windows上进行游戏开发。使用某些opengl库(freeglut,glew)时,我只需要使用“ cl file.c”进行编译,并且如果我在当前目录中具有正确的dll文件,它将可以正常运行。

但是对于SDL,我必须明确提供lib文件,例如“ cl sdlprog.c SDL2.lib SDL2main.lib”。我还必须指出它是带有“ / link / subsystem:console”的控制台程序。

为什么我需要为SDL做这些事情?无需提及lib文件,opengl程序即可正常编译。

我确保所有lib文件都位于正确的位置。它们位于我放置opengl lib文件的位置。

1 个答案:

答案 0 :(得分:2)

某些库是通过函数指针动态加载和访问的。在这些情况下,不必在编译时显式链接库。其他库可以静态链接,不需要动态加载,但链接在编译时完成。还有一些链接在一起的编译时库,但是它们只是为动态加载过程提供了易于使用的界面。一个很好的例子是Win32 PE文件中的导入地址表。例如,在ntdll库中可以找到对NtTerminateProcess的调用。您可以通过调用LoadLibrary和GetProcAddress动态调用NtTerminateProcess,也可以选择链接它的编译时间来为您创建接口。但是,仍然需要在运行时动态加载ntdll。链接它的编译时间并不是一成不变的,它只是允许您调用NtTerminateProcess而无需使用LoadLibrary / GetProcAddress。

所以问题归结为静态链接与opengl在做什么之间的区别。或sdl要求的动态链接。正如我前面提到的,动态加载在运行时为要加载的模块分配内存,并将其加载到操作系统指定的地址中。已有一篇文章对此稍作介绍:

Difference between static linking and dynamic linking

difference between dynamic loading and dynamic linking?

使用静态链接时,如果库发生更改,则需要重新编译二进制文件。在动态链接的情况下,您不必仅重新编译dll的二进制文件。