【问题标题】:Equivalent of import libraries in LinuxLinux 中导入库的等价物
【发布时间】:2019-05-10 12:06:52
【问题描述】:

在 Windows C++ 中,当您想要链接到 DLL 时,您必须提供导入库。但是在 GNU 构建系统中,当您想要链接与 dll 等效的 .so 文件时,您不需要。为什么是这样?是否有等效的 Windows 导入库。

注意:我没有谈论在 Windows 中使用 GNU C++ 的情况,在这种情况下你也必须使用导入库。分界线在 Windows C++ 和 Linux C++ 之间。

【问题讨论】:

  • 标准 C++ 是为抽象硬件设计的。它忽略了操作系统和实现细节。
  • 不要将 Linux 视为等同于 Windows 的东西。用新的眼光看待 Linux!
  • 您只需链接到库。例如,要链接到libssl.so,您将在命令字符串中包含-lssl(您的选项中不包含lib 部分(例如-lssl)。如果库不在您添加的标准搜索路径中-L/path/to/lib 将该目录添加到搜索路径。(如果需要其他部分,该库必须知道它所在的位置。在构建库时,链接器 -rpath 选项可以提供帮助。
  • (注:这个问题与C++语言无关)好吧,导入库只包含可以自动生成链接时间的代码。实际上,这就是 gcc-for-windows (mingw) 所做的:它可以链接 *.dll 文件而不使用 *.lib 文件。注意:永远不要使用包含 ordinals 的 *.lib 文件:您可能会得到无法在不同版本的 Windows 上运行的可执行文件。

标签: c++ linux windows gnu


【解决方案1】:

Windows 和 Linux 中的链接模型不同。阅读 Levine 的书 Linkers and loaders(在 Linux 上,library 的每个公共 symbol 都会被导出,除非你玩 visibility 技巧;在 Windows 上,情况并非如此,并且需要明确导出的符号)。

C++11 标准(阅读n3337)没有提到动态链接。这是一个实现细节。

未来C++20 可能会有modules

Linux 中没有“导入库”。

有关更多详细信息,请注意 name mangling 是不同的。另请阅读Program Library Howto,Drepper 的How to Write Shared Libraries

在 Linux 上,pluginsdynamic loader 加载(和处理与在 Windows 上不同)。见ld-linux(8)dlopen(3)dlsym(3)elf(5)

在 Linux 上使用 objdump(1)readelf(1)nm(1) 检查 ELF 文件(object fileslibrariesexecutables)。

另见C++ dlopen mini howto。另请阅读Visibility 函数attribute。另请参阅this 问题。

.so 文件,相当于 dll

Linux shared objectELF .so 文件)并不完全等同于 Windows DLL。阅读上面给出的参考资料。

我还推荐阅读Operating Systems: Three Easy Pieces 和旧的Advanced Linux Programming(两者都可以免费下载)。稍后阅读syscalls(2) 以及从那里引用的页面。

请注意,Linux 是free software,因此您可以下载并研究其大部分组件的源代码。

PS。 Linux 和 Windows 确实不同。不要期望在 Linux 中找到与每个 Windows 功能完全相同的功能。 以全新的眼光看待 Linux。 利用 Linux 是由免费软件组成的优势,并考虑研究源代码,例如kernelbinutils、GNU libcmusl-libc(两者都提供了一些 ld-linux.solibc.so,所以是 C standard library)、GCCClang6367(都提供了 @98 @上方libc.so)。

【讨论】:

  • 我的情况或多或少与 OP 的情况相反,我了解 Linux 的系统,但我正在尝试更详细地了解 Windows dll。您是否有更多关于导出符号需要明确的意思的信息?那是__declspec(dllexport) 不是吗?是否真的说 Windows dll 根本没有任何导出的符号,并且无法自行链接,这就是您需要导入 .lib 文件的原因吗?这就是它的样子。此外,程序库 HowTo 链接似乎已失效。编辑:找到这个stackoverflow.com/a/27899384
  • 我这辈子都没用过 Windows。
  • 这个答案可能包含正确的事实,但它们与问题完全无关,因为可以链接到只有 DLL 的 Windows DLL。 Windows 版本的 gcc 可以做到这一点。 Microsoft 的链接器不会直接处理 DLL,但只能使用完全自动从 DLL 生成的文件进行链接。在 Windows 上使用导入库不是链接模型差异的结果,而是 Microsoft 链接器中采用的快捷方式(我会慷慨地说优化,因为它们可能确实减少了链接时间)。
【解决方案2】:

要添加到 Basile 的答案,您可能偶尔需要在 Linux 上导入库来模拟共享库的 delay loading(这很有用,例如,如果您的应用很少需要此库并且您不想在其上浪费资源)。

这样的模拟导入库将由一堆包装器组成,它们在内部调用dlopendlsym,然后转到共享库中的实现。它们可以通过项目特定脚本或通用工具Implib.so手动实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 2021-03-01
    相关资源
    最近更新 更多