DLL文件到底是什么,它们如何工作?


224

DLL文件如何工作?其中似乎有很多,但我不知道它们是什么或它们如何工作。

那么,他们有什么关系呢?


6
由于仅在Windows上标记了该问题,并且该问题早在2008年就已经写了,所以值得一提的是,当今dll也可以在.NET Core和Mac和Linux上运行。
Jim Aho

Answers:


287

什么是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加载资源。

进一步阅读:

请检查MSDNWikipedia以进一步阅读。也是这个答案的来源。


5
应该在某处提到导入库。好吧,我现在走开。:)
Adam Mitz

2
删除了那些似乎已解决的问题。我如何为此获得积分?<g>
Adam Mitz

36

什么是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


2
请在句子("The .NET platform might not face this issue at all.")后面加上原因。谢谢。
Jogi,2016年

1
@RehanKhan从.NET Framework v2.0开始,运行时将仅加载使用.NET版本编译的程序集,其中<=当前加载的运行时+ .NET还会缓存加载程序集的失败尝试+如果先前的调用已经找到了程序集,则CL运行时将使用已经加载的程序集。总而言之,我认为说它们通过对程序运行时将加载哪些DLL施加非常严格的限制(在它放弃并寻求您的帮助之前)施加了非常严格的限制,可以说是最好的选择。
弗拉迪斯拉夫·马丁

14

假设您正在制作一个使用库中某些函数的可执行文件。

如果您使用的库是静态的,则链接器将直接从库中复制这些函数的目标代码,并将它们插入可执行文件中。

现在,如果运行了此可执行文件,则它具有所需的一切,因此可执行加载程序仅将其加载到内存中并运行它。

如果该库是动态的,则链接器将不会插入目标代码,而是会插入一个存根,该存根基本上表示此函数位于此DLL中的此位置。

现在,如果运行此可执行文件,则可执行文件的某些位(即存根)将丢失,因此加载程序将通过可执行文件来修复丢失的存根。只有在解决所有存根之后,才允许可执行文件运行。

若要查看此操作,请删除或重命名DLL,并观察尝试运行可执行文件时加载程序将如何报告缺少的DLL错误。

因此,名为动态链接库的链接过程的一部分是在运行时由可执行加载程序动态完成的。

最后一点,如果您不链接到DLL,则链接器将不会插入任何存根,但是Windows仍提供GetProcAddress API,该API允许您在可执行文件启动后很长时间加载执行DLL函数的入口点。


12

DLL(动态链接库)和SL(共享库,在UNIX下等效)仅是可执行代码的库,可以在加载时动态链接到可执行文件中。

静态库在编译时插入到可执行文件中,并从那时开始进行修复。它们增加了可执行文件的大小,无法共享。

动态库具有以下优点:

1 /它们是在运行时而不是编译时加载的,因此它们可以独立于可执行文件进行更新(您在Windows中看到的所有奇特的窗口和对话框都来自DLL,因此无需您就可以更改应用程序的外观必须重写)。

2 /因为它们是独立的,所以代码可以在多个可执行文件之间共享-这样可以节省内存,因为如果您使用单个DLL运行100个应用程序,则内存中可能只有DLL的一个副本。

它们的主要缺点是优势#1-使DLL独立于应用程序更改可能会导致应用程序停止工作或以奇怪的方式开始运行。DLL版本控制在Windows下往往无法很好地管理,这导致了古怪的“ DLL Hell”。


11

DLL文件包含一个导出表,该是可以由调用程序查找的符号列表。这些符号通常是具有C调用约定__stcall)的函数。导出表还包含函数的地址。

使用此信息,即使在编译时没有访问DLL,调用程序也可以在DLL中调用函数。

引入动态链接库具有更多信息。


6

http://support.microsoft.com/kb/815065

DLL是一个库,其中包含可同时由多个程序使用的代码和数据。例如,在Windows操作系统中,Comdlg32 DLL执行常见的对话框相关功能。因此,每个程序都可以使用此DLL中包含的功能来实现“打开”对话框。这有助于促进代码重用和有效的内存使用。

通过使用DLL,可以将程序模块化为单独的组件。例如,会计程序可以按模块出售。如果已安装每个模块,则可以在运行时将其加载到主程序中。由于模块是分开的,因此程序的加载时间更快,并且仅在请求该功能时才加载模块。

此外,更新更容易应用于每个模块,而不会影响程序的其他部分。例如,您可能有一个薪资计划,并且税率每年都会变化。将这些更改隔离到DLL后,您可以应用更新,而无需再次生成或安装整个程序。

http://en.wikipedia.org/wiki/Dynamic-link_library



1

DLL(动态链接库)包含一个或多个应用程序或服务使用的资源。它们可以包含类,图标,字符串,对象,接口,以及除UI之外几乎所有开发人员需要存储的所有内容。


3
他们实际上可以存储UI,并且几个程序可以执行此操作。例如管理单元。
Brian R. Bondy

1

据微软

(DLL)动态链接库是包含运行应用程序所需的数据,代码或资源的文件。这些是Windows生态系统创建的文件,可以在两个或多个应用程序之间共享。

当程序或软件在Windows上运行时,应用程序的工作方式在很大程度上取决于程序的DLL文件。例如,如果特定应用程序具有多个模块,则每个模块之间的交互方式由Windows DLL文件确定。

如果需要详细说明,请查看这些有用的资源

什么是dll文件关于dll文件

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.