【问题标题】:Why do I have to provide *.lib files I'm using to the compiler for only some libraries?为什么我必须为编译器提供仅用于某些库的 *.lib 文件?
【发布时间】:2019-06-10 00:26:29
【问题描述】:

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

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

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

我确保所有的 lib 文件都在正确的位置。它们与我放置 opengl lib 文件的位置相同。

【问题讨论】:

  • 依赖项的使用机制因 SDK 而异。例如:您提到的 glew 构建,例如,在他们的网站上明确指出,当使用共享库配置时,“请记住在 Windows 上将您的项目与 glew32.lib、glu32.lib 和 opengl32.lib 链接,并且Unix 上的 libGLEW.so、libGLU.so 和 libGL.so (-lGLEW -lGLU -lGL)。” 关于您的问题,简单的答案是因为 SDL 作者选择提供他们的库以供使用,他们可能是the best source to ask
  • 您能发布您的 sdlprog.c 文件的一部分吗?我对预处理器宏(以 # 开头的行)感兴趣。
  • @CristiFati 从那时起我就删除了它,因为它只是一个初始化 sdl 的小测试程序。但我很确定它只是一个#include ,SDL2 存在的原因是因为我将 sdl 的标头放在 include\SDL2 中。
  • 您应该提供一个 MCVE ([SO]: How to create a Minimal, Complete, and Verifiable example (mcve)),其中应包含代码、构建它的命令、错误以及成功的命令。

标签: c windows compilation linker cl


【解决方案1】:

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

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

Difference between static linking and dynamic linking

difference between dynamic loading and dynamic linking?

使用静态链接,如果您的库发生变化,您将需要重新编译二进制文件。在动态链接的情况下,您不必只重新编译 dll 二进制文件。

【讨论】:

    猜你喜欢
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    相关资源
    最近更新 更多