当前位置: 首页 > article >正文

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,也可以使用动态加载的方式,但会增加一些复杂性。

http://www.kler.cn/a/458804.html

相关文章:

  • vue视频录制 限制大小,限制时长
  • 逆向生成原理
  • 当下热点系列 篇二:大消费题材解析和股票梳理
  • KubeOS
  • Android着色器SweepGradient渐变圆环,Kotlin
  • BurstAttention:高效的分布式注意力计算框架
  • YOLOv8实战车辆目标检测
  • js混淆中 p[‘name‘] 来访问属性的好处
  • 若依前后端分离项目部署(使用docker)
  • C++ 设计模式:职责链模式(Chain of Responsibility)
  • MySQL:一文弄懂时区time_zone
  • 远程调用服务器jupter调试程序
  • word运行时错误‘-2147221164(80040154)’ 没有注册类的解决办法
  • C++ 设计模式:备忘录模式(Memento Pattern)
  • omi friend实战记录
  • Java重要面试名词整理(十六):SpringBoot
  • 基于springboot的美容院管理系统设计与实现(java项目源码+文档)
  • 代码随想录Day37 动态规划:完全背包理论基础,518.零钱兑换II,本周小结动态规划,377. 组合总和 Ⅳ,70. 爬楼梯(进阶版)。
  • React Native中的核心技术概念
  • 【GridView渐进全解】第一部分GridView基础
  • 前端参数formData格式
  • 扬声器阵列的波束成形相关的关键技术和国内外研究现状
  • 未授权访问漏洞
  • AF3 AtomTransformerBlock类解读
  • SpringBoot数据字典字段自动生成对应code和desc
  • 硬件设计-硬件 EMC 设计规范