关于 Dynamic-Link 库

动态链接允许模块仅包含加载时或运行时查找导出的 DLL 函数所需的信息。 动态链接不同于更熟悉的静态链接,其中链接器将库函数的代码复制到调用它的每个模块中。

动态链接的类型

在 DLL 中调用函数有两种方法:

  • 加载时动态链接中,模块显式调用导出的 DLL 函数,就像它们是本地函数一样。 这要求将模块与包含函数的 DLL 的导入库链接。 导入库为系统提供加载 DLL 所需的信息,并在加载应用程序时查找导出的 DLL 函数。
  • 运行时动态链接中,模块使用 LoadLibraryLoadLibraryEx 函数在运行时加载 DLL。 加载 DLL 后,模块调用 GetProcAddress 函数以获取导出的 DLL 函数的地址。 该模块使用 GetProcAddress 返回的函数指针调用导出的 DLL 函数。 这样就不需要导入库了。

DLL 和内存管理

加载 DLL 的每个进程都会将其映射到其虚拟地址空间。 进程将 DLL 加载到其虚拟地址后,可以调用导出的 DLL 函数。

系统维护每个 DLL 的每个进程引用计数。 当线程加载 DLL 时,引用计数将增加 1。 当进程终止时,或者当引用计数变为零 (运行时动态链接仅) 时,将从进程的虚拟地址空间中卸载 DLL。

与任何其他函数一样,导出的 DLL 函数在调用它的线程的上下文中运行。 因此,以下条件适用:

  • 调用 DLL 的进程线程可以使用 DLL 函数打开的句柄。 同样,调用进程的任何线程打开的句柄都可以在 DLL 函数中使用。
  • DLL 使用调用线程的堆栈和调用进程的虚拟地址空间。
  • DLL 从调用进程的虚拟地址空间分配内存。

有关 DLL 的详细信息,请参阅以下主题: