C++笔记-对windows平台上lib和dll的进一步理解(2024-10-21
背景
最近将linux上的程序移植到windows上,发现linux上动态库就so,而windows上有lib和dll。其实在大学时期就发现过这个情况了,只是不能理解,工作的这几年时间,都是基于Linux上的开发,很少在windows上进行开发。这次终于理解了大学时期对windows上lib与dll之间的理解了。
Linux上的动态库
在理解windows上时,首先说下linux下的动态库。
在 Linux 中,.so(Shared Object)文件通常包含以下几部分信息:
1. 头部信息
- ELF Header:标识这个文件是一个 ELF(Executable and Linkable Format)文件,并提供关于文件格式和结构的基本信息,如文件类型、机器架构等。
2. 程序头表(Program Header Table)
- 描述了如何将文件映射到内存中的信息,包含各个段的地址、大小和属性等。
3. 节(Section)
- 代码段(.text):包含实际的可执行代码。
- 数据段(.data):存储初始化的全局变量和静态变量。
- BSS段(.bss):存储未初始化的全局变量和静态变量。
- 符号表(.symtab):存储函数和变量的名称及其地址,用于链接。
- 字符串表(.strtab):存储符号表中的字符串(如函数名、变量名)。
4. 重定位信息
- 包含使用动态链接时需要进行重定位的地址信息。这个部分用于在程序加载时修正地址。
5. 动态段(.dynamic)
- 包含动态链接器需要的信息,如需要链接的库、依赖的符号等。
6. 导出符号(Exported Symbols)
- 指明哪些符号(函数、变量等)可供其他程序使用。这是共享库的关键部分,使得其他程序可以链接到这个共享对象。
7. 初始化和清理函数
- 定义在 .init 和 .fini 段中,分别用于库加载时和卸载时调用的初始化和清理函数。
总结
这些组成部分使得 .so 文件能够在运行时被动态加载、链接和执行。
windows上的lib和dll
在C++中,动态链接库(DLL)和静态链接库(LIB)是两种不同的文件,它们的目的和使用方法各有不同。以下是它们的主要区别:
DLL(Dynamic Link Library)
- 功能:DLL 是在运行时被加载的库,可以被多个程序共享使用。这意味着不同的程序可以使用同一份 DLL,从而节省内存并减小磁盘空间。
- 更新:如果 DLL 中的代码有更新,只需要替换 DLL 文件,而不需要重新编译依赖它的程序。
- 文件格式:DLL 文件包含可执行代码、数据和资源,并且可以在程序运行时动态载入。
LIB(Library)
- 功能:在 Windows 下,LIB 文件有两种类型:一种是用于静态链接的库,另一种是用于动态链接的进口库(import library)。在动态链接的情况下,LIB 文件通常是 DLL 的一种描述,提供了 DLL 中的函数和类的接口。
- 静态链接:如果 LIB 是静态链接库,链接时会将库的代码直接打包到可执行程序中。
- 动态链接:动态链接情况下,LIB 文件包含了 DLL 中的函数的地址信息。当程序需要调用 DLL 中的函数时,会通过这个 LIB 文件链接。
在 Windows 下使用
- 当编写一个第三方编译库时,通常提供 DLL 和对应的 LIB 文件,以便其他开发者可以轻松链接到这个库。
- DLL 提供了实际的实现和代码,而 LIB 文件则提供了接口,帮助编译器找到 DLL 中的函数。
总结
Windows 需要提供 LIB 来描述 DLL 的接口,而 Linux 的 SO 文件通过自身的设计,实现了足够的接口描述,因此只需提供一个文件。
Windows上部署和开发
windows上当程序编译成成品软件后,部署时就只需要dll了,但如果要搭建开发环境,就必须要lib进行参与,除非在代码中指定函数名,使用这种方式就只需要dll了。
部署成品软件
- 仅需 DLL:当你编译好了一个程序并准备部署时,只需要把 DLL 文件放到应用程序目录或系统路径中。这样,应用程序在运行时可以加载这个 DLL。
搭建开发环境
- 需要 LIB:如果你想让其他开发者能够编译和链接他们的程序到这个 DLL,就需要提供相应的 LIB 文件。LIB 文件包含了 DLL 中函数的接口信息,帮助编译器找到函数的实现。
指定函数名
- 是的,如果开发者在代码中手动指定函数名(通常使用 LoadLibrary 和 GetProcAddress),就不需要 LIB 文件。这样的话,他们直接通过 DLL 获取函数指针,调用时通过函数指针来执行。但是,这种方式会使代码更复杂,因为需要处理函数指针的类型转换。
总结
- 部署时,仅需要 DLL;开发时,方便起见通常使用 LIB。
- 如果直接用 DLL,也可以使用动态加载的方式,但会增加一些复杂性。