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

动静态库

在这里插入图片描述

一、静态库(.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.hqwc.cn/news/60153.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven出现报错 ; Unable to import maven project: See logs for details错误的多种解决方法

问题现象; IDEA版本&#xff1a; Maven 版本 &#xff1a; 3.3.9 0.检查 maven 的设置 &#xff1a;F:\softeware\maven\apache-maven-3.9.3\conf 检查setting.xml 配置 本地仓库<localRepository>F:\softeware\maven\local\repository</localRepository>镜像…

Improved Deep Metric Learning with Multi-class N-pair Loss Objective

Improved Deep Metric Learning with Multi-class N-pair Loss Objective 来源&#xff1a; NIPS’2016NEC Laboratories America 文章目录 Improved Deep Metric Learning with Multi-class N-pair Loss ObjectiveDistance Metric LearningDeep Metric Learning with Multip…

redis的持久化

第一章、redis的持久化 1.1&#xff09;持久化概述 ①持久化可以理解为将数据存储到一个不会丢失的地方&#xff0c;Redis 的数据存储在内存中&#xff0c;电脑关闭数据就会丢失&#xff0c;所以放在内存中的数据不是持久化的&#xff0c;而放在磁盘就算是一种持久化。 ②为…

python实现简单的爬虫功能

前言 Python是一种广泛应用于爬虫的高级编程语言&#xff0c;它提供了许多强大的库和框架&#xff0c;可以轻松地创建自己的爬虫程序。在本文中&#xff0c;我们将介绍如何使用Python实现简单的爬虫功能&#xff0c;并提供相关的代码实例。 如何实现简单的爬虫 1. 导入必要的…

Python中的dataclass:简化数据类的创建

Python中的dataclass是一个装饰器&#xff0c;用于自动添加一些常见的方法&#xff0c;如构造函数、__repr__、__eq__等。它简化了创建数据类的过程&#xff0c;减少了样板代码&#xff0c;提高了代码的可读性和可维护性。有点类似java里面的Java Bean。 让我们看一个简单的例子…

Vscode无法写入文件 NoPermissions (FileSystemError): Error: EACCES: permission

用Vscode想要新建一个index.html的时候遇到了下图问题&#xff0c;说没有权限无法写入文件。 没有权限&#xff0c;咱们给他加上权限哈哈哈&#xff0c;博主是Mac电脑&#xff0c;如下操作&#xff1a; 1.找到你项目的根目录&#xff0c;右键&#xff0c;点击“显示简介”。 …

【非欧几里得域信号的信号处理】使用经典信号处理和图信号处理在一维和二维欧几里得域信号上应用低通滤波器研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

vue3+element-plus点击列表中的图片预览时,图片被表格覆盖

文章目录 问题解决 问题 视觉 点击图片进行预览&#xff0c;但还能继续选中其他的图片进行预览&#xff0c;鼠标放在表格上&#xff0c;那一行表格也会选中&#xff0c;如图所示第一行的效果。 代码 <el-table-column prop"id" label"ID" width"…

React源码解析18(1)------ React.createElement 和 jsx

1.React.createElement 我们知道在React17版本之前&#xff0c;我们在项目中是一定需要引入react的。 import React from “react” 即便我们有时候没有使用到React&#xff0c;也需要引入。原因是什么呢&#xff1f; 在React项目中&#xff0c;如果我们使用了模板语法JSX&am…

MySQL单表查询

单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varch…

工程监测仪器振弦传感器信号转换器应用于隧洞监测

工程监测仪器振弦传感器信号转换器应用于隧洞监测 隧洞建设是重大工程项目&#xff0c;监测隧洞结构和环境的变化对确保隧洞安全和运行管理至关重要。工程监测仪器是实现隧洞监测的关键设备&#xff0c;其中振弦传感器和信号转换器是非常重要的组成部分。 振弦传感器是一种专门…

《Linux从练气到飞升》No.10 冯洛依曼体系结构

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…