DLL 和 LIB 文件 - 啥以及为啥?

Posted

技术标签:

【中文标题】DLL 和 LIB 文件 - 啥以及为啥?【英文标题】:DLL and LIB files - what and why?DLL 和 LIB 文件 - 什么以及为什么? 【发布时间】:2010-10-29 03:50:32 【问题描述】:

我对 DLL 和 LIB 知之甚少,只知道它们包含程序正常运行所需的重要代码 - 库。但是为什么编译器会生成它们呢?将所有代码包含在一个可执行文件中不是更容易吗? DLL 和 LIB 的区别是什么?

【问题讨论】:

fileinfo.com/extension/lib 【参考方案1】:

有静态库 (LIB) 和动态库 (DLL) - 但请注意,.LIB 文件可以是静态库(包含目标文件)或导入库(包含允许链接器链接到 DLL 的符号)。

使用库是因为您可能拥有要在许多程序中使用的代码。例如,如果您编写一个计算字符串中字符数的函数,该函数将在许多程序中很有用。一旦你让那个函数正常工作,你就不想每次使用它时都重新编译代码,所以你把那个函数的可执行代码放在一个库中,链接器可以提取编译后的代码并将其插入你的程序.出于这个原因,静态库有时被称为“档案”。

动态库更进一步。让库函数的多个副本在每个程序中占用空间似乎很浪费。为什么他们不能都共享该功能的一份副本?这就是动态库的用途。与其在编译时将库代码构建到程序中,不如在加载到内存时将其映射到程序中来运行它。同时运行的多个程序使用相同的功能可以共享一份,节省内存。实际上,您可以仅根据需要加载动态库,具体取决于代码的路径。如果您不进行任何打印,那么让打印机例程占用内存毫无意义。另一方面,这意味着您必须在运行程序的每台机器上安装动态库的副本。这会产生一系列问题。

例如,几乎每个用“C”编写的程序都需要一个名为“C 运行时库”的库中的函数,尽管很少有程序需要所有这些函数。 C 运行时有静态和动态两种版本,因此您可以根据特定需求确定您的程序使用哪个版本。

【讨论】:

原来.LIB 文件可以是静态库(包含目标文件)或导入库(包含允许链接器链接到 DLL 的符号)。 I'm wondering why this is so. 很好的解释!代码是共享的,而数据(默认情况下)在使用 Dll 的应用程序之间不共享。 @Lumi:好点。就 DLL 而言,我们有两种类型的链接。 隐式链接,当我们有一个由 DLL 创建者提供的 .lib 文件以及适当的标头时;这个.lib只是目标DLL的描述符,它包含地址、入口点等,但没有代码。这个.lib 必须传递给链接器。第二个是显式链接,当我们通过LoadLibrary函数手动加载DLL时。在这种类型中,我们不需要 .lib 文件,但我们必须花一点力气找到 DLL 导出及其地址,并通过指针调用这些函数。 请问,如果我的项目中包含 header(.h) 和 c(.c) 文件,是否需要库才能编译和运行可执行文件?我不是说这个的利弊,只要它能够编译和运行【参考方案2】:

另一个区别在于性能。

由于 DLL 在运行时由 .exe(s) 加载,因此 .exe(s) 和 DLL 使用共享内存概念,因此性能相对于静态链接而言较低。

另一方面,.lib 是在编译时静态链接到每个请求的进程的代码。因此 .exe(s) 将具有单个内存,从而提高进程的性能。

【讨论】:

从 lib 或 DLL 运行的代码之间没有性能影响。【参考方案3】:

DLL 是在其他可执行程序之间共享的函数库。只需查看您的 windows/system32 目录,您就会发现其中有几十个。当您的程序创建 DLL 时,它通常还会创建一个 lib 文件,以便应用程序 *.exe 程序可以解析在 DLL 中声明的符号。

.lib 是静态链接到程序的函数库——它们不被其他程序共享。每个与 *.lib 文件链接的程序都包含该文件中的所有代码。如果您有两个程序 A.exe 和 B.exe 与 C.lib 链接,那么每个 A 和 B 都将包含 C.lib 中的代码。

如何创建 DLL 和库取决于您使用的编译器。每个编译器的做法都不同。

【讨论】:

【参考方案4】:

另一个方面是安全性(混淆)。一旦从主应用程序中提取一段代码并放入“分离的”动态链接库,就更容易攻击、分析(逆向工程)代码,因为它已被隔离。当同一段代码保存在 LIB 库中时,它是已编译(链接)目标应用程序的一部分,因此很难将该段代码与其余目标二进制文件隔离(区分)。

【讨论】:

安全方面对我来说是新的。如果 C# 应用程序调用本机非托管 C++ dll,上述推理是否成立? 但是 LIB 也是隔离的,不是吗?因此,攻击者可以简单地分析 LIB。或者,LIB 不向公众开放是一种常见的情况吗? LIB 也是“孤立的”,就编译器进程而言,但是一旦链接器将这些部分放在一起,LIB 就是 EXE 的一部分,无法与您自己的区别代码。【参考方案5】:

创建 DLL/LIB 而不仅仅是将代码编译成可执行文件的一个重要原因是重用和重定位。普通的 Java 或 .NET 应用程序(例如)很可能会使用多个第 3 方(或框架)库。仅针对预构建库进行编译会更容易和更快,而不必将所有 3rd 方代码编译到您的应用程序中。将代码编译到库中还可以鼓励良好的设计实践,例如设计您的类以用于不同类型的应用程序。

【讨论】:

以上是关于DLL 和 LIB 文件 - 啥以及为啥?的主要内容,如果未能解决你的问题,请参考以下文章

vc下DLL项目设置dll和lib库输出路径以及使用lib/dll库时的包含路径

lib 和 dll 的区别生成以及使用详解

dll库和lib库有啥区别?

VC6.0 设置动态链接库工程生成dll以及lib文件的位置

为啥类库 (dll) 也不生成 lib 文件?

opencv中自带的dll和lib 为啥不能直接使用?