【问题标题】:Implicit vs. Explicit linking to a DLL隐式与显式链接到 DLL
【发布时间】:2011-06-15 04:59:31
【问题描述】:

何时应隐式或显式链接到 DLL,常见做法或陷阱是什么?

【问题讨论】:

  • 显式与隐式是什么意思?你的意思是使用 LoadLibrary 还是静态链接?
  • @tenfour 隐式是当您使用 .h 并且需要链接到 .lib 时,当您分别使用 LoadLibrary 和 GetProcAddress 时是显式的。静态链接是另一种口香糖。
  • 当您手头没有 .lib 文件时,有时您会使用显式。
  • 我知道 MSDN 说“隐式链接有时被称为静态加载”,但说 DLL 的静态链接非常令人困惑。

标签: winapi dll dllimport windows


【解决方案1】:

我同意其他已经回答您的人的观点(Hans Passant 和 shoosh)。我只想添加两件事:

1) 必须使用LoadLibraryGetProcAddress 的一种常见情况如下:您只想使用新版本Windows 中存在的一些新API,但该API 在您的应用程序中并不重要。所以你用LoadLibraryGetProcAddress测试你需要的功能是否存在,并在案例中使用。如果函数不存在,您的程序会做什么完全取决于您的实现。

2) 您的问题中没有包含一个重要选项:delayed loading of DLLs。在这种情况下,操作系统将在调用其函数之一时加载 DLL,而不是在应用程序启动时加载。它允许在某些第一次使用显式链接的情况下使用导入库(.lib 文件)。此外,它改善了应用程序的启动时间,并被 Windows 本身广泛使用。所以也推荐这种方式。

【讨论】:

  • 延迟加载由 Visual Studio 链接器实现,而不是操作系统。它会为您插入适当的 LoadLibraryGetProcAddress 呼叫。操作系统不知道是谁打了这些电话。这就是为什么它可以追溯到 Window 95,即使该功能是在 98 中引入的。
  • @MSalters:你错了。程序可执行文件 (PE) 使用的延迟加载有额外的IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 部分。
【解决方案2】:

显式链接 DLL 是相当罕见的。主要是因为它很痛苦且容易出错。您需要为导出的函数编写函数指针声明,并正确获取 LoadLibrary + GetProcAddress + FreeLibrary 代码。仅当您需要对插件样式 DLL 的运行时依赖项或想要根据配置从一组 DLL 中进行选择时,您才需要这样做。或者处理版本控制,例如仅在更高版本的 Windows 上可用的 API 函数。显式链接是 COM 和 .NET DLL 的默认设置。

更多背景信息见MSDN Library article

【讨论】:

    【解决方案3】:

    我假设您指的是使用.lib 链接与使用LoadLibrary() 动态加载DLL。

    通过链接到其.lib 静态加载DLL 通常更安全。链接阶段检查编译时是否存在所有入口点,并且您不会加载不具有您期望的功能的 DLL。不必使用GetProcAddress() 也更容易。

    所以通常你应该只在绝对需要时才使用动态加载。

    【讨论】:

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