【问题标题】:Where exactly do dll's get loaded? [duplicate]dll究竟在哪里被加载? [复制]
【发布时间】:2014-02-15 02:13:41
【问题描述】:

我相信这个问题已经被问过很多次了,我已经阅读了大量的文章,但我仍然不知道 不明白。 DLL 究竟在哪里加载?我说的是 DLL 的实际代码。当我打电话给 MessageBoxA 时,它会跳转到哪里?代码是加载到我自己的进程中,还是跳转到其他地方(甚至不确定这是否可能)?

请赐教,这个问题困扰了我很长时间,但我似乎无法弄清楚。

【问题讨论】:

  • 快速思考一下:DLL 被加载到进程内存空间中。因此,如果有 5 个程序使用同一个 DLL,则该 lib 将占用内存中的 5 个位置;这与通过中断处理程序或 COM 对象共享的代码不同,它们驻留在自己的单个内存空间中,而不管有多少正在运行的程序需要它。

标签: windows dll


【解决方案1】:

每个进程加载一次DLL。以下是更多细节:

From Wikipedia:

DLL 在调用进程的内存空间中执行,具有相同的访问权限

this Stack Overflow answer中所述:

每个进程最多加载一次 DLL。因此,如果您的 DLL 被多个其他 DLL 使用,它仍然会在每个进程中存在一次。

MSDN has plenty more details:

系统为每个 DLL 维护每个进程的引用计数。当线程加载 DLL 时,引用计数加一。当进程终止或引用计数变为零时(仅限运行时动态链接),DLL 将从进程的虚拟地址空间中卸载。 与任何其他函数一样,导出的 DLL 函数在调用它的线程的上下文中运行。因此,适用以下条件:

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

On Variable Scope:

在 DLL 源代码文件中声明为全局的变量被编译器和链接器视为全局变量,但每个加载给定 DLL 的进程都会获得自己的该 DLL 全局变量的副本。静态变量的范围仅限于声明静态变量的块。因此,默认情况下,每个进程都有自己的 DLL 全局变量和静态变量实例。

在加载 DLL 之前,必须先找到它们。关于 Windows 如何搜索 DLL,有一些特定的规则,例如 Dynamic-Link Library Search Order 中列出的规则。

【讨论】:

    猜你喜欢
    • 2013-12-16
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    相关资源
    最近更新 更多