【基础IO】动静态库 {动静态库的创建和使用;动态库的加载;默认优先使用动态链接;为什么要有库;动态链接的优缺点;静态链接的优缺点;一些有趣的库}

news2024/11/25 2:56:55

动静态库

在这里插入图片描述

一、静态库(.a)

1.1 如何创建静态库?

  1. 编写源文件与头文件。注意:库的源文件没有main函数!

在这里插入图片描述

  1. 将所有的源文件编译生成目标文件。(如果只提供.h和.o给用户,用户也可以成功编译运行。但这样的做法太过麻烦,且容易出错。)

在这里插入图片描述

  1. 利用ar工具将所有的目标文件归档生成静态库。注意:静态库文件的前缀是lib后缀是.a!

在这里插入图片描述

提示:ar是gnu归档工具,用于归档生成静态库。rc选项表示replace and create。

  1. 打包发布静态库:为静态库创建目录,并将头文件和库文件分开存放。

在这里插入图片描述

  1. 自动化生成并发布静态库
    在这里插入图片描述

1.2 如何使用静态库?

先将静态库拷贝给用户

在这里插入图片描述

方法一:

  1. 将头文件和库文件直接拷贝到系统的默认搜索路径下

    • gcc头文件的默认搜索路径:/usr/include

    • gcc库文件的默认搜索路径:/lib64 or /usr/lib64

    在这里插入图片描述

  2. gcc会自动链接C静态库(libc.a),第三方库需要带-l选项指定要链接的库。注意:这里的库名称是要去掉lib前缀和.a后缀的!

    在这里插入图片描述

提示:我们将库拷贝到系统默认搜索路径下的操作,就叫做库的安装!

方法二:通过-I-L选项指定头文件和库文件的所在路径,并用-l指明要链接的库

在这里插入图片描述


二、动态库(.so)

2.1 如何创建动态库?

  1. 编写源文件与头文件。注意:库的源文件没有main函数!
  2. 将所有的源文件编译生成目标文件。注意:生成动态库的目标文件要加-fPIC选项,生成与位置无关的目标文件

在这里插入图片描述

注意:

  1. 所谓与位置无关,即动态库采用相对编址的方式:动态库并没有被合并到可执行程序中,编译和链接时分配的地址是相对地址(偏移量):在程序执行时由运行时链接器加载库。将库中数据加载到内存中后,每个使用了动态库的程序都要根据加载的起始位置计算内部函数以及变量的地址。
  2. 而静态库采用绝对编址的方式:静态库的代码是被合并到可执行程序中的,其变量和指令的地址在编译和链接时就已经确定,并且在程序执行时保持不变。
  1. 通过gcc -shared命令将所有的目标文件归档生成动态库。注意:动态库文件的前缀是lib后缀是.so!

在这里插入图片描述

  1. 打包发布动态库:为动态库创建目录,并将头文件和库文件分开存放。(此处包含静态库)

在这里插入图片描述

  1. 自动化生成并发布动态库(此处包含静态库)
    在这里插入图片描述

2.2 如何使用动态库?

2.2.1 动态库的加载

在这里插入图片描述

  1. 静态库代码会同程序代码合并在一起,程序运行时被直接加载到进程地址空间的代码区。

  2. 动态库代码在调用时才会被加载到内存并通过页表建立与地址空间的映射关系。动态库代码会被加载到地址空间的共享区。

  3. 如果有多个进程同时调用了同一个动态库,只需要向内存加载一次。之后只要建立页表映射关系即可。因此,动态库也被成为共享库。

  4. 将动态库从磁盘加载到内存并建立与进程地址空间映射关系的工作,由操作系统链接器完成。


2.2.2 动态库的使用

先将动态库拷贝给用户

在这里插入图片描述

方法一:

  1. 安装库:将头文件和库文件直接拷贝到系统的默认搜索路径下
  2. 编译程序,带-l选项指定要链接的库

方法二:

  1. 通过-I-L选项指定头文件和库文件的所在路径,并用-l指明要链接的库

    在这里插入图片描述

    为什么动态链接后会报错:找不到动态库文件?就是因为动态链接器的运行时链接库缓存中没有对应动态库的路径。

  2. 向动态链接器缓存中添加动态库路径

    1. 可以将动态库拷贝到/lib64路径下,加载器默认会在该路径下进行搜索。

      在这里插入图片描述

    2. 我们还可以在/lib64路径下创建动态库文件的软链接。

      在这里插入图片描述

    3. 还可以在环境变量LD_LIBRARY_PATH中添加动态库的所在路径,加载器也会在环境变量中的路径下搜索动态库。
      在这里插入图片描述

      注意:修改环境变量,只是修改了bash缓冲区中的内容。只在本次登录中有效

    4. 还可以在bash的资源配置文件.bashrc中,添加登录时导入LD_LIBRARY_PATH环境变量的操作。

    5. 我们还可以通过在/etc/ld.so.conf.d/目录下添加配置文件的方法,永久性的添加动态库的搜索路径。

      在这里插入图片描述

      提示:ldconfig是一个用于配置动态链接器运行时的命令。它用于更新动态链接器的运行时链接库缓存,以便在程序运行时能够正确地找到和加载动态库。


三、默认优先使用动态链接

此时的lib目录下既有动态库(.so)又有静态库(.a),编译链接的程序是动态链接还是静态链接?

  1. 如果目录下只有静态库:有动态库就动态链接,没有动态库也只能静态链接。(此时lib目录下没有libmylib.so)
    在这里插入图片描述
  2. 如果目录下动静态库同时存在,gcc默认优先使用动态链接。
    在这里插入图片描述
  3. 如果动静态库同时存在,非要使用静态库呢?-static选项:摒弃默认优先使用动态库的原则,所有库都直接使用静态链接方案。
    在这里插入图片描述

三、为什么要有库?

  • 站在使用者的角度:库的存在可以大大减少使用者的开发周期;同时使用高质量的库还可以提高软件本身的质量。

  • 站在开发者的角度:可以使合作开发更加简单;同时也隐藏了源码,提高了代码安全性。

3.1 静态链接的优缺点

优点:

  1. 独立性:静态链接使得可执行文件成为一个独立的实体,不需要依赖外部的库文件。这意味着可执行文件可以在没有其他依赖项的情况下运行,更加方便和可移植。
  2. 简单部署:由于静态链接将所有依赖项都打包到可执行文件中,部署和分发可执行文件变得更加简单。只需将可执行文件复制到目标系统上,而不需要担心库文件的版本兼容性或缺失。
  3. 性能优化:静态链接可以在编译时进行优化,将库的代码和数据与主程序一起进行优化和整合。这可以提高程序的执行效率和性能,因为编译器可以进行更多的优化和内联操作。

缺点:

  1. 内存占用:静态链接会导致每个可执行文件都包含其所需的库和依赖项的副本,这会占用更多的内存空间。如果多个程序同时使用相同的库,每个程序都需要加载和占用相同的库的副本,造成内存浪费。
  2. 更新和维护:静态链接的可执行文件中包含了所有的库和依赖项,当库或依赖项发生更新时,需要重新编译和重新部署整个可执行文件。这增加了更新和维护的复杂性,尤其是在大型项目中或者涉及多个依赖项的情况下。
  3. 文件大小:由于静态链接将所有的库和依赖项都打包到可执行文件中,导致可执行文件的大小增加。这可能会增加程序的下载时间和存储空间的消耗。

3.2 动态链接的优缺点

优点:

  1. 节省内存:动态链接允许多个程序共享同一个库的实例,避免了每个程序都加载和占用相同库的副本,从而节省了内存空间。
  2. 减少页面交换:当使用动态链接时,操作系统只需要将库文件的代码和数据加载到内存中一次,然后多个程序可以共享这些库的实例。这减少了需要从磁盘加载和卸载库文件的次数,减少了页面交换的频率。
  3. 灵活更新:当库文件发生更新时,只需要更新库文件本身,而不需要重新编译和部署整个程序。这样可以简化更新和维护的过程,节省时间和资源。
  4. 减少程序体积:由于库文件是独立存在的,可执行文件只需要包含自身的代码和数据,因此可执行文件的体积相对较小。

缺点:

  1. 运行时依赖:动态链接需要依赖外部的库文件,如果库文件缺失或版本不兼容,程序可能无法正常运行。这增加了程序在不同环境中的部署和兼容性的挑战。
  2. 性能损失:动态链接需要在运行时加载和链接库文件,这会引入一定的性能开销。相比静态链接,动态链接的程序可能稍微慢一些。
  3. 部署复杂性:动态链接需要确保系统中存在正确的库文件,并设置正确的库路径。这可能需要额外的配置和管理工作,增加了部署的复杂性。

3.3 一些有趣的库

  1. ncurses:字符界面库

    ncurses库是一个用于创建基于终端的交互式应用程序的库。它提供了一套API,用于处理终端界面的输入和输出,以及控制终端的光标位置、颜色、窗口等。

    使用ncurses库,您可以在终端中创建复杂的文本界面,包括窗口、菜单、按钮、文本框等。您可以使用函数来控制光标的位置,以及在终端上输出文本和图形。此外,ncurses库还提供了处理键盘和鼠标输入的功能,以及对终端的颜色和属性进行控制。

    ncurses库的安装和使用请看这篇文章:【Linux拓展】ncurses库的安装和使用 {ncurses库的安装方法,ncurses库的使用手册,基于终端的贪吃蛇游戏}_芥末虾的博客-CSDN博客

  2. Boost:C++准标准库

    Boost是一个开源的、跨平台的C++库集合,提供了许多高质量、可移植且广泛使用的组件和工具,涵盖了从基本的数据结构和算法到高级的并发编程和网络编程等各个领域。

    Boost库的特点包括:

    1. 高质量:Boost库的组件经过了严格的测试和评审,具有高质量和稳定性,广泛应用于工业和学术界。

    2. 可移植性:Boost库的组件可以在多个平台上运行,包括Windows、Linux、Mac等。

    3. 开源:Boost库是开源的,可以免费使用和修改。

    Boost库提供了丰富的功能,包括但不限于以下几个方面:

    1. 智能指针:Boost库提供了多种智能指针,如shared_ptr、scoped_ptr等,用于管理动态分配的内存,避免内存泄漏和悬空指针等问题。

    2. 容器和算法:Boost库提供了许多扩展了标准库的容器和算法,如unordered_map、unordered_set、foreach等,方便开发者进行数据处理和算法实现。

    3. 并发编程:Boost库提供了多线程、原子操作、线程池等并发编程的工具和组件,简化了多线程编程的复杂性。

    4. 正则表达式:Boost库提供了强大的正则表达式库,支持正则表达式的匹配、替换、分割等操作。

    5. 文件系统:Boost库提供了对文件系统的操作接口,方便开发者进行文件和目录的创建、删除、遍历等操作。

    6. 网络编程:Boost库提供了网络编程的工具和组件,包括TCP/UDP套接字、异步IO、网络协议等,方便开发者进行网络应用的开发。

    总之,Boost库是一个功能强大、广泛应用的C++库集合,可以提高开发效率,增加代码的可靠性和可移植性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/856935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8个值得收藏的在线3D建模工具

如今,许多设计师、艺术家和建筑师尝试学习进行 3D 建模来表达他们的想法。 但 3D 建模并不总是看起来那样。 我们所有人都很难找到合适的工具,尤其是在学习阶段。 但不要害怕! 你可以学习仅使用浏览器进行建模。 有许多基于浏览器的 3D 建模…

Scala(第六章 面向对象)

文章目录 6.1 Scala包 6.1.1 包的命名6.1.2 包说明(包语句)6.1.3 包对象6.1.4 导包说明 6.2 类和对象 6.2.1 定义类6.2.2 属性 6.3 封装 6.3.1 访问权限6.3.2 方法6.3.3 创建对象6.3.4 构造器6.3.5 构造器参数 6.4 继承与多态6.5 抽象类 6.5.1 抽象属性和…

实例034 直接在窗体上绘图

实例说明 含有Graphics对象的控件都能够在其上进行绘图,很多软件就是通过Graphics对象来美化程序的主界面,因为窗体中含有Graphics对象,所以可以将窗体看作一个大画板,一个可以在上面绘图的特殊控件。本例设计了一个简单的绘图软…

Pycharm 双击启动失败?

事故 双击 Pycharm 后,出现加载工程,我不想加载这个工程,就点击了弹出的 cancle 取消按钮。然后再到桌面双击 Pycharm 却发现无法启动了。哪怕以管理员权限运行也没用,就是不出界面。 原因未知 CtrlshiftESC 打开后台&#xff…

什么是埋阻埋容工艺?

PCB埋阻埋容工艺是一种在PCB板内部埋入电阻和电容的工艺。通常情况下,PCB上电阻和电容都是通过贴片技术直接焊接在板面上的,而埋阻埋容工艺则将电阻和电容嵌入到PCB板的内部层中,这种印制电路板,其自下而上依次包括第一介电层&…

uniapp支付宝微信支付功能实现

大纲: 具体实现逻辑如下: 页面初始化时,通过onLoad方法获取传入的钱包(wallet)信息。 用户输入充值金额,使用watch监听输入值的变化,并更新选中的充值金额选项。判断金额是否大于0,若是小于0,则…

【对于一维信号的匹配】对一个一维(时间)信号y使用自定义基B执行匹配追踪(MP)研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

43.字符串相乘

目录 一、题目 二、代码 一、题目 43. 字符串相乘 - 力扣(LeetCode) 二、代码 class Solution { public: string addStrings(string num1, string num2)//求两个字符串相加 {int end1 num1.size() - 1;int end2 num2.size() - 1;int next 0;//进位…

分布式定时任务框架Quartz总结和实践(1)

一、概述 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或…

springboot mybatis鲜花商城平台

伴随着互联网技术的进步,各种电商平台也如雨后 春笋不断涌现。一个好的电商平台应该具有用户体验度高,用户信息安全等特点, 从而可以满足更多的用户需求。现有的电商平台虽然在不断完善,但仍然存在着 不少问题。本设计是一个基于java的spring…

租赁OLED透明屏:打造独特商业体验的智慧选择

近年来,OLED透明屏技术在商业领域中迅速崛起,其高透明度和卓越的图像质量为商家创造了全新的展示方式。 租赁OLED透明屏作为一种智慧选择,不仅能提升品牌形象和吸引力,还能创造与众不同的视觉体验。 对此,尼伽将和大…

【Eureka技术指南】「SpringCloud」从源码层面让你认识Eureka工作流程和运作机制(上)

前言介绍 了解到了SpringCloud,大家都应该知道注册中心,而对于我们从过去到现在,SpringCloud中用的最多的注册中心就是Eureka了,所以深入Eureka的原理和源码,接下来我们要进行讲解下eureka的源码分析,由此应…

Oracle数据迁移

问题描述: oracle数据库的所有表结构、数据、索引等需要需从测试库迁移到正式库。 解决步骤: oracle数据库迁移,主要通过expdp从测试库所在的源服务器将指定的数据表或数据源导出为一个或多个数据文件(.dmp文件)&…

第五届太原理工大学新生赛(决赛)题解

题解&#xff09; <font colorred>第五届太原理工大学新生赛&#xff08;决赛&#xff09;:star:A.810975:star2:<font colorgreen>题意:cherries:<font colorred>解决思路:pear:代码 :star:<font colorpink>B.hammer玩游戏:star2:<font colorgreen…

STM32--综述

文章目录 前言STM32简介STM32F103C8T6系统结构Keil软件安装注意事项新建工程操作流程 前言 本专栏将学习B站江协科技的STM32入门教程&#xff0c;通过自身理解和对老师的总结所写的博客专栏。 STM32简介 STM32是意法半导体&#xff08;STMicroelectronics&#xff09;公司推…

5.3.10.静态映射表建立过程分析

5.3.10.静态映射表建立过程分析 5.3.10.1、建立映射表的三个关键部分 (1)映射表具体物理地址和虚拟地址的值相关的宏定义 https://blog.csdn.net/liangzuzong/article/details/131994560 (2)映射表建立函数&#xff08;宏定义&#xff09;。该函数负责由(1)中的映射表来建立li…

以太网TCP协议(十二)

目录 一、概述 二、功能 2.1 连接管理 2.2 响应与序列号 2.3 超时重发 2.4 传输单位&#xff1a;段 2.5 窗口控制 2.6 流控制 2.7 拥塞控制 2.8 效率提高 三、报文格式 一、概述 TCP作为一种面向有连接的协议&#xff0c;只有在确认通信对端存在时才会发送数据&…

SD-MTSP:蜘蛛蜂优化算法SWO求解单仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)

一、蜘蛛蜂优化算法SWO 蜘蛛蜂优化算法&#xff08;Spider wasp optimizer&#xff0c;SWO&#xff09;由Mohamed Abdel-Basset等人于2023年提出&#xff0c;该算法模型雌性蜘蛛蜂的狩猎、筑巢和交配行为&#xff0c;具有搜索速度快&#xff0c;求解精度高的优势。蜘蛛蜂优化算…

Hugging Face 的文本生成和大语言模型的开源生态

[更新于 2023 年 7 月 23 日: 添加 Llama 2。] 文本生成和对话技术已经出现多年了。早期的挑战在于通过设置参数和分辨偏差&#xff0c;同时控制好文本忠实性和多样性。更忠实的输出一般更缺少创造性&#xff0c;并且和原始训练数据更加接近&#xff0c;也更不像人话。最近的研…

论文研读-SIMD系列-基于分区的SIMD处理及在列存数据库系统中的应用

基于分区的SIMD处理及在列存数据库系统中的应用 单指令多数据&#xff08;SIMD&#xff09;范式称为列存数据库系统中优化查询处理的核心原则。到目前为止&#xff0c;只有LOAD/STORE指令被认为足够高效&#xff0c;可以实现预期的加速&#xff0c;并且认为需要尽可能避免GATHE…