【发布时间】:2010-09-12 13:53:28
【问题描述】:
DLL 文件究竟是如何工作的?它们的数量似乎很多,但我不知道它们是什么或它们是如何工作的。
那么,他们是怎么回事?
【问题讨论】:
-
由于这只是用 Windows 标记的,而且这个问题是在 2008 年写的,值得一提的是,现在 dll 也可以使用 .NET Core 在 Mac 和 Linux 上运行。
DLL 文件究竟是如何工作的?它们的数量似乎很多,但我不知道它们是什么或它们是如何工作的。
那么,他们是怎么回事?
【问题讨论】:
什么是 DLL?
动态链接库 (DLL) 类似于 EXE,但它们不能直接执行。它们类似于 Linux/Unix 中的 .so 文件。也就是说,DLL是MS对共享库的实现。
DLL 非常像 EXE,文件格式本身是相同的。 EXE 和 DLL 都基于可移植可执行 (PE) 文件格式。 DLL 还可以包含 COM 组件和 .NET 库。
DLL 包含什么?
DLL 包含 EXE 或其他 DLL 使用的函数、类、变量、UI 和资源(例如图标、图像、文件等)。
库类型:
几乎在所有操作系统上,都有两种类型的库。静态库和动态库。在 Windows 中,文件扩展名如下:静态库 (.lib) 和动态库 (.dll)。主要区别在于静态库在编译时链接到可执行文件;而动态链接库直到运行时才链接。
更多关于静态和动态库的信息:
您通常不会在计算机上看到静态库,因为静态库直接嵌入在模块(EXE 或 DLL)中。动态库是一个独立的文件。
DLL 可以随时更改,并且只有在 EXE 显式加载 DLL 时才会在运行时加载。静态库一旦在 EXE 中编译就无法更改。 DLL 可以单独更新,而不需要更新 EXE 本身。
加载 DLL:
程序在启动时、通过 Win32 API LoadLibrary 或当它是另一个 DLL 的依赖项时加载 DLL。程序使用 GetProcAddress 加载函数或 LoadResource 加载资源。
进一步阅读:
【讨论】:
什么是 DLL?
DLL 文件是可以包含可执行代码和资源(如图像等)的二进制文件。与应用程序不同,这些文件不能直接执行,但应用程序会在需要时加载它们(或在启动期间一次性加载)。
它们重要吗?
大多数应用程序会在启动时加载它们所需的 DLL 文件。如果没有找到其中任何一个,系统将根本无法启动该过程。
DLL 文件可能需要其他 DLL 文件
与应用程序需要 DLL 文件的方式相同,DLL 文件可能依赖于其他 DLL 文件本身。如果在依赖链中找不到这些 DLL 文件之一,则不会加载应用程序。这可以使用任何依赖遍历器工具轻松调试,例如 Dependency Walker。
系统文件夹里有这么多
大多数系统功能以 DLL 文件的形式向用户程序公开,因为它们是共享代码/资源的标准形式。每个功能都单独保存在不同的 DLL 文件中,以便只加载所需的 DLL 文件,从而减少系统的内存限制。
已安装的应用程序也使用 DLL 文件
DLL 文件也成为物理分离功能的一种形式,如上所述。好的应用程序也会尝试在绝对需要之前不加载 DLL 文件,从而减少内存需求。这也会导致应用程序附带大量 DLL 文件。
DLL 地狱
但是,当共享的 DLL 文件与需要它们的程序之间存在版本不匹配时,系统升级经常会破坏其他程序。系统检查点和DLL缓存等一直是M$解决这个问题的举措。 .NET 平台可能根本不会遇到这个问题。
我们如何知道 DLL 文件中的内容?
您必须使用像 DUMPBIN 或 Dependency Walker 这样的外部工具,它不仅可以显示 DLL 文件中包含哪些公开可见的函数(称为导出),还可以显示它需要哪些其他 DLL 文件以及从这些文件中导出哪些此 DLL 文件所依赖的 DLL 文件。
我们如何创建/使用它们?
请参阅供应商提供的编程文档。对于 C++,请参考 MSDN 中的LoadLibrary。
【讨论】:
"The .NET platform might not face this issue at all.") 并说明原因。谢谢。
假设您正在制作一个使用库中的某些函数的可执行文件。
如果您使用的库是静态的,链接器将直接从库中复制这些函数的目标代码并将它们插入到可执行文件中。
现在,如果运行这个可执行文件,它就拥有了它需要的所有东西,所以可执行文件加载器只需将它加载到内存中并运行它。
如果库是动态的,链接器将不会插入目标代码,而是会插入一个存根,该存根基本上表示此函数位于此位置的 DLL 中。
现在,如果运行此可执行文件,则缺少可执行文件的位(即存根),因此加载程序会通过可执行文件修复丢失的存根。只有在所有存根都被解析后,可执行文件才能被允许运行。
要查看实际情况,请删除或重命名 DLL,并观察加载程序在您尝试运行可执行文件时如何报告丢失的 DLL 错误。
因此得名动态链接库,部分链接过程由可执行加载器在运行时动态完成。
最后一点,如果您不链接到 DLL,则链接器不会插入存根,但 Windows 仍然提供 GetProcAddress API,允许您加载并执行 DLL可执行文件启动很久之后的函数入口点。
【讨论】:
DLL(动态链接库)和 SL(共享库,在 UNIX 下等效)只是可执行代码库,可以在加载时动态链接到可执行文件。
静态库在编译时插入到可执行文件中,并从那时起固定。它们会增加可执行文件的大小并且无法共享。
动态库具有以下优点:
1/ 它们是在运行时而不是编译时加载的,因此它们可以独立于可执行文件进行更新(您在 Windows 中看到的所有花哨的窗口和对话框都来自 DLL,因此您的应用程序的外观可以无需重写即可更改)。
2/ 因为它们是独立的,所以代码可以在多个可执行文件之间共享 - 这可以节省内存,因为如果您使用单个 DLL 运行 100 个应用程序,内存中可能只有一个 DLL 副本。
它们的主要缺点是优点 #1 - 让 DLL 独立于您的应用程序更改可能会导致您的应用程序停止工作或开始以奇怪的方式运行。 DLL 版本控制在 Windows 下往往不能很好地管理,这导致了古怪的命名为“DLL Hell”。
【讨论】:
DLL 文件包含一个导出表,它是一个可以由调用程序查找的符号列表。这些符号通常是带有C calling convention (__stcall) 的函数。导出表还包含函数的地址。
有了这些信息,调用程序就可以调用 DLL 中的函数,即使它在编译时没有访问 DLL 的权限。
【讨论】:
http://support.microsoft.com/kb/815065
DLL 是一个包含代码的库 和可以被超过 同时一个程序。为了 例如,在 Windows 操作系统中, Comdlg32 DLL 执行常见的 对话框相关功能。 因此,每个程序都可以使用 包含的功能 这个 DLL 来实现一个打开对话框 盒子。这有助于促进代码重用和 有效的内存使用。
通过使用 DLL,程序可以 模块化成独立的组件。 例如,一个会计程序可能 按模块出售。每个模块都可以 在运行时加载到主程序中 安装该模块的时间。 因为模块是分开的, 程序的加载时间更快, 并且只有在那个时候才加载一个模块 请求功能。
此外,更新更容易 适用于每个模块而不影响 程序的其他部分。为了 例如,您可能有工资单 程序,并且税率每个变化 年。当这些变化被隔离时 到 DLL,您可以应用更新 无需构建或安装 再看一遍整个程序。
【讨论】:
DLL 是一种文件扩展名和被称为“动态链接库”的文件格式,用于保存 Windows 程序的多个代码和过程。软件和游戏基于 DLL 文件运行;创建 DLL 文件是为了让多个应用程序可以同时使用它们的信息。
如果您想获取有关 DLL 文件的更多信息或遇到任何错误,请阅读以下帖子。 https://www.bouncegeek.com/fix-dll-errors-windows-586985/
【讨论】:
DLL(动态链接库)包含一个或多个应用程序或服务使用的资源。它们可以包含类、图标、字符串、对象、界面以及开发人员需要存储的几乎所有内容,除了 UI。
【讨论】:
根据微软的说法
(DLL) 动态链接库是包含应用程序运行所需的数据、代码或资源的文件。这些是由 Windows 生态系统创建的文件,可以在两个或多个应用程序之间共享。
当程序或软件在 Windows 上运行时,应用程序的工作方式很大程度上取决于程序的 DLL 文件。例如,如果一个特定的应用程序有几个模块,那么每个模块如何相互交互由 Windows DLL 文件决定。
如果您需要详细说明,请查看这些有用的资源
【讨论】: