【问题标题】:Misconception about static/implicit linking Vs dynamic/explcit linking关于静态/隐式链接与动态/显式链接的误解
【发布时间】:2020-02-24 18:00:05
【问题描述】:

我最近了解到静态链接和隐式链接是basically the same thing,只是不同的命名法。我的理解是,当您静态(隐式)链接到二进制文件时,根据定义链接到*.lib(windows)或*.a(linux)文件,通常在cmake中使用target_link_libraries。另一方面,当您显式链接(在 Windows 上使用 LoadLibrary)时,您根据定义链接到 *.dll 文件(或 Linux 上的 *.so)(并且没有相应的 cmake 命令,因为所有工作都在内部完成实际代码)。

但是,在multiple places 中,我读到有人提到静态/隐式链接到dll 文件,这让我很困惑。很明显,我的知识在某个地方存在漏洞,我希望这里有人可以堵住它。

编辑

有人指出,这个问题主要指的是windows,它确实如此。但是,我目前正在尝试生成跨平台代码,因此我仍然对这些概念如何(或是否)推广到其他平台感兴趣。

【问题讨论】:

  • 这些东西因操作系统而异。
  • 当您在本机可执行文件c++ 中使用.NET / CLR 时会链接到.dll,您链接到导入库或使用.def 或直接使用LoadLibrary
  • 如果这些东西因不同的操作系统而不同,那么尝试使用 cmake 编写跨平台共享库是否有意义?
  • 尝试使用 cmake 编写跨平台共享库是否有意义? 是的。您可能想看看像itk 这样的 Kitware 软件,他们如何处理在不同平台上构建共享库。在将代码库转换为跨平台之前,请先尝试小型示例项目。
  • 使用运行时动态链接让您可以通过SetDefaultDllDirectoriesAddDllDirectory 控制DLL 搜索路径,这比加载时链接的默认DLL 搜索路径更安全,后者包括工作目录和PATH。但是通过LoadLibraryExWGetProcAddress 手动链接很乏味,因为您必须为编译器指定函数原型才能生成正确的代码。 Windows 有更好的办法:delayed loading.

标签: c++ windows linker static-linking dynamic-linking


【解决方案1】:

实际上有 3 种不同类型的链接,而不是 2 种。

对于 UNIX:

  1. 链接到归档(又名静态)库:

    gcc main.o libfoo.a

  2. 链接到动态(又名共享)库:

    gcc main.o libfoo.so

  3. 链接到libdl,它允许您dlopen 任意其他共享库(在链接时不需要存在):

    gcc main.o -ldl

2 和 3 都涉及动态链接器(并且正在使用共享库),但程度不同。

在 Windows 上存在等价物:当您链接到 foo.lib 时,您使用的是任一 1 或 2,这取决于 foo.lib 是否包含实际代码,或引用 foo.dll

当您使用LoadLibrary 时,您属于第 3 种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多