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 是在运行时被加载的库,可以被多个程序共享使用。这意味着不同的程序可以使用同一份 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,也可以使用动态加载的方式,但会增加一些复杂性。
相关推荐
Dirschs16 分钟前
【Ubuntu22.04安装ROS Noetic】
linux·ubuntu·ros
qianshanxue1122 分钟前
ubuntu 操作记录
linux
宝山哥哥3 小时前
网络信息安全学习笔记1----------网络信息安全概述
网络·笔记·学习·安全·网络安全
AmosTian3 小时前
【系统与工具】Linux——Linux简介、安装、简单使用
linux·运维·服务器
十秒耿直拆包选手3 小时前
Qt:主窗体(QMainwindow)初始化注意事项
c++·qt
荔枝吻4 小时前
【保姆级喂饭教程】Windows下安装Git Flow
windows·git·git flow
逼子格4 小时前
逻辑门电路Multisim电路仿真汇总——硬件工程师笔记
笔记·硬件工程师·multisim·电路仿真·逻辑门·硬件工程师学习·电路图
@Hwang4 小时前
【ESP32-IDF笔记】09-UART配置和使用
笔记·esp32·uart·esp32s3·esp32-idf
霖005 小时前
C++学习笔记三
运维·开发语言·c++·笔记·学习·fpga开发
mit6.8245 小时前
[shad-PS4] Vulkan渲染器 | 着色器_重新编译器 | SPIR-V 格式
c++·游戏引擎·ps4