在编译时链接共享对象
在 Windows 中,许多 .dll 都带有静态 .lib 对应项。我的理解是,.lib 对应部分基本上包含 LoadProcAddress 调用,以便程序员不必自己执行此操作。本质上是节省时间。当我切换到 Linux 时,我假设情况是相同的,将 .dll 替换为 .so,将 .lib 替换为 .a,但我遇到的情况表明这是错误的,我不知道是什么正在进行中:
我正在使用一个以 .a/.so 对形式提供的库。我正在链接 .a,但是当我对生成的二进制文件执行 ldd 时,它不包含对相应 .so 文件的引用。然后,我尝试链接 .so 文件,令我惊讶的是,这有效。此外,当我对生成的二进制文件执行 ldd 时,.so 文件出现了。
所以,我真的很困惑到底发生了什么。在 Windows 中,我绝不会想到链接到 .dll 文件。另外,在 Windows 中,如果 .dll 文件附带有 .lib,并且我在编译时链接到 .lib,那么我希望在运行时对相应的 .dll 有依赖关系。在本例中,这两件事都不成立。
是的,我已经阅读了有关 Linux 中共享对象的基本教程,但我读到的所有内容似乎都表明我最初的假设是正确的。顺便说一句,我应该提到我正在使用 Code::Blocks 作为 IDE,我知道这会使事情变得复杂,但我 99% 确定当我告诉它链接到 .so 文件时,它并不是简单地交换出.a 文件,因为生成的二进制文件较小。 (加上关于 ldd 的整个事情......)
无论如何,提前致谢。
In Windows, many .dlls come with a static .lib counterpart. My understanding is that the .lib counterpart basically contains LoadProcAddress calls so that the programmer doesn't have to do it him/herself. Essentially, a time saver. When I switched to Linux, I was assuming the situation was the same, replacing .dll with .so and .lib with .a, but I have come to a situation that is showing me this is wrong and I can't figure out what is going on:
I am using a library that comes as a .a/.so pair. I was linking against the .a, but when I executed ldd on the binary that was produced, it contained no reference to the corresponding .so file. So then, I tried linking against the .so file and to my surprise, this worked. In addition, the .so file showed up when I executed ldd against the resulting binary.
So, I am really confused as to what is going on. In Windows, I would never think to link against a .dll file. Also, in Windows, if a .dll file was accompanied with a .lib and I linked against the .lib at compile-time, then I would expect to have a dependency on the corresponding .dll at runtime. Both these things are not true in this case.
Yes, I have read the basic tutorials about shared objects in Linux, but everything I read seems to indicate that my initial assumption was correct. By the way, I should mention that I am using Code::Blocks as an IDE, which I know complicates things, but I am 99% sure that when I tell it to link against the .so file, it is not simply swapping out the .a file because the resulting binary is smaller. (Plus the whole business about ldd...)
Anyway, thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是预料之中的。当您静态链接时,静态库的代码将集成到生成的二进制文件中。不再有对静态库的引用或依赖。
静态链接不起作用是什么意思?没有理由不应该...
This is expected. When you link statically, the static library's code is integrated into the resulting binary. There are no more references to or dependencies on the static library.
What do you mean, that the static linking did not work? There's no reason that it shouldn't...
.lib 在 Windows 中用于动态链接。 Linux 中没有它们,您可以直接与 .so 链接。
.a 文件是静态构建的库,您可以使用它来静态链接。
.lib are used in Windows to dynamically link. You don't have them in Linux, you link with .so directly.
The .a file is the statically built library, you use it to link statically.
要添加 tharibo 已经正确的答案 - 在某些情况下(例如延迟共享库加载),可能需要以 Windows 方式执行此操作,即通过链接静态存根而不是
.so
。此类存根可以手动编写,也可以通过特定于项目的脚本或通用 Implib.so 工具生成。To add to already correct answer by tharibo - in some situations (e.g. delayed shared library load) it might be desirable to do it the Windows way i.e. by linking against a static stub instead of
.so
. Such stubs can be written by hand, generated by project-specific scripts or by generic Implib.so tool.