【Linux】动静态库

2023-11-04

1.动静态库的原理

源文件和头文件形成一个可执行文件需要经历以下的四个步骤

  • 预处理:展开头文件,宏替换,条件编译等,最后形成.i文件
  • 编译:完成词法分析、语法分析、词义分析、符号汇总等。将代码翻译成汇编指令,最后形成.s文件
  • 汇编:将汇编指令转换成二进制的机器码,最后形成.o文件
  • 链接:将各个.o文件链接,最后形成可执行文件。

比如下面需要用eg1.c,eg2.c,eg3.c,eg4.c和mian.c形成可执行文件,需要以下的步骤:

在这里插入图片描述

如果其他项目也需要用到eg1.c,eg2.c,eg3.c,eg4.c文件,那么形成可执行文件的步骤是相同的。
在这里插入图片描述

这里eg1.c,eg2.c,eg3.c,eg4.c被反复的使用,如果将这些.c文件打包在一起,就形成了库,所以库本质上就是一堆.o文件的集合,往往这些文件集合,提供了大量的可调用方法。

在这里插入图片描述

2.动态库和静态库基础

静态库(.a):**在编译链接的时候直接将整个库的代码整合复制到可执行文件中,**程序运行的时候不再需要静态库,所以使用静态库的形成的文件往往比较大。

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 动态库在编译的时候,在程序中只有一个指向的位置。

  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
  • 也就是说可执行文件在需要使用动态函数的时候,程序才会去读取函数库。
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

3.动静态库的实现

3.1设计一个静态库

准备下面的几个文件

mymath.h和mymath.c

在这里插入图片描述

myprint.c和myprint.h

在这里插入图片描述

将上面的mymath.c和myprint.c编译生成对应的xxx.o文件,下面编写对应的Makfile

在这里插入图片描述

编写Makefile

在这里插入图片描述

ar是gnu归档工具,rc表示(replace and create)

在这里插入图片描述

最后生成了对应的静态库。

发布静态库

在使用库的时候,需要什么东西?

库文件和头文件。

在这里插入图片描述

执行make static发布静态库

在这里插入图片描述

3.2设计一个动态库

shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so

 gcc -fPIC -c sub.c add.c
 gcc -shared -o libmymath.so *.o
  • fpIC将对于的文件加载到物理内存中,允许加载到物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

  • shared:将动态库发布,形成共享库的格式

编写对应的Makefile

在这里插入图片描述

生成对应的动态库并发布

在这里插入图片描述

4.动静态库的使用

上面我们实现了动静态并发布,下面讲解如何使用动静态库;

我们将动态库和静态库放在一个test目录下进行测试。

cp lib-static test/ -rf
cp lib-dyl test/ -rf
4.1静态库的使用

在这里插入图片描述

在使用静态库前,需要知道库里面有那些方法。

然而在包头文件时,我们依然发现找不到静态库中的头文件。

在这里插入图片描述

解决方案一:

指定头文件的路径,这个用法在实际工程中重要不大。

在这里插入图片描述

解决方案二:

头文件的搜索路径:

  • 对于" "形式的头文件,是在当前(进程)路径查找。
  • 对应<>形式的头文件,是在系统头文件下查找。

所以:我们可以考虑将自己的头文件和库文件拷贝到系统路径下。

  • /usr/include这个路径下,存放了系统头文件
  • /lib64路径下,存放了系统的动静态库

在这里插入图片描述

cp lib-static/include/* /usr/include 	#将静态库下的所有头文件拷贝到系统头文件路径下
cp lib-static/lib/*  /lib64/				#将静态库下的所有库拷贝到系统路径下。

#要使用自己的库,-l需要指定第三方库的名字
gcc -o test main.c -lmymath

在这里插入图片描述

一个库的库名需要去掉前缀lib和后缀,静态库需要去掉lib和.a

在这里插入图片描述

注意:

方案二这种做法,容易污染操作系统的头文件和库,所以一般不推荐这种写法,除非是大佬写的库。

解决方案三:

指定路径:文件搜索路径

gcc ~~~ -I 头文件路径 -L 库文件路径 -l库名(去掉前缀lib和后缀)

在这里插入图片描述

4.2动态库的使用

方案一

将文件拷贝到系统路径,使用方法和静态库的使用方法相似。这种方法并不推荐

方案二:指定路径

使用方法:

gcc 依赖关系 -I 头文件路径 -L库文件理解 -l库文件名

在这里插入图片描述

为什么静态库生成的可执行程序可以成功执行,而动态库生成的无法执行?

程序和动态库是分开加载的。

在动静态库原理中我们提到过,链接静态库是直接拷贝静态库的内容,所以可执行程序不需要再依赖静态库

而动态库只是加一了一个指向,指向动态库的位置,而可执行程序执行是一个新的进程,所以需要重新链接动态库。

可执行程序如何链接动态库?

  • 将动态库拷贝到/lib64/中

在这里插入图片描述

这种方法会污染系统库文件,所以不推荐

  • 导入环境变量

程序在运行时,会在自己的环境变量**【LD_LIBRARY_PATH】**,中查找自己的动态库路径。

在这里插入图片描述

由于配置过Vim,所以与默认的有些不同。

接下来,可以将动态库的路径导入到LD_LIBRARY_PATH。

在这里插入图片描述

命令行式导入环境变量只在该shell中有效,重启后需要重新配置。

方案三:配置.conf文件

ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

在这里插入图片描述

动态库在运行时,还会扫描该路径【/etc/ld.so.conf.d/】下的配置文件。

在这里插入图片描述

所以我们可以创建一个动态库的配置文件,将动态库的路径加入配置文件中。

在这里插入图片描述

ldconfig 命令可以加载配置文件。然后程序就可以正常运行

在这里插入图片描述

ldd 文件:可以查看文件的链接信息。

在这里插入图片描述

方案四:在系统库中建立到动态库的软连接

由于动态库会自动搜索系统库文件,所以可以在系统库中建立导入的动态库的软连接

sudo ln -s 动态库绝对路径 /lib64/软连接名

在这里插入图片描述

4.3动态库的多进程共享原理

被加载到内存中的动态库,通过页表映射到了该进程地址空间中的共享区中,在运行时,则需要再次通过页表的映射,找到物理内存中的动态库。所以进程在运行时需要再次扫描物理内存。

而静态库在连接的过程中,代码则是被拷贝到可执行程序中,静态库则存放在每个进程的代码段,每个静态连接的进程都持有一份,所以静态库和进程可以分离。

在这里插入图片描述

如果有其他的进程动态链接了动态库:

在这里插入图片描述

所以动态链接有下面的特点:

  • 动态库(.so),程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间 。

一些好玩的库

比如ncurse,Linux下的图形化界面库;boost,很经典的C++库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】动静态库 的相关文章

随机推荐

  • Spring高手之路5,Dubbo服务注册与发现(文末送书)

    目录 一 介绍 1 介绍 Dubbo 服务注册与发现的基本概念和重要性 2 阐述 Dubbo 服务注册与发现的实现方式和应用场景 二 Dubbo 服务注册与发现的架构设计 1 Dubbo 服务注册与发现的总体架构设计 2 Dubbo 服务提
  • stm32(六)中断

    什么是中断呢 可以举一个日常生活中的例子来说明 假如你正在给看书 电话铃响了 这时 你放下手中的书 记录下你看书的页数 去接电话 通话完毕 再继续从原来的位置继续看书 这个例子就表现了中断及其处理过程 电话铃声使你暂时中止当前的看书的动作
  • Flink-CDC实践(含实操步骤与截图)

    文章目录 前言 Flink CDC 1 CDC简介 1 1 什么是 CDC 1 2 CDC 的种类 1 3 Flink CDC 2 Flink CDC 案例实操 2 1 DataStream 方式的应用 2 1 1 导入依赖 2 1 2 编
  • DM达梦如何再修改了端口好的情况登录

    1 登录DM的disql 再bin目录下输入disql 输入用户名和密码 即可登录 也可以不用输入用户名和密码 直接敲连个空格 就可以直接登录 不过前提是用户名和密码都是默认密码 2 如果端口不是默认5236 那么这种登录方式 也就不起作用
  • 常见的内存泄漏原因和解决方案

    常见的内存泄漏原因和解决方案 1 全局引用 问题 在JavaScript代码中 使用全局变量或全局对象来保存对DOM元素或其他对象的引用 这可能导致内存泄漏 解决方案 避免使用全局变量或全局对象 改用合适的作用域来管理变量和对象的生命周期
  • 【STM32】-串口调试中软硬件问题定位过程分享

    1 概述 串口调试中难免会遇到问题 对于新手来说 会觉得无从下手 或急于修改代码 查找软件原因 本文将分享调试中遇到的问题及排故思路 供读者参考 学习 2 问题描述 在将原工程文件移植到原子阿波罗开发板 其他开发板类似 后 上位机无法接收到
  • 【毕业设计】人脸识别算法研究与实现 - 深度学习 机器学习

    文章目录 0 前言 1 机器学习 人脸识别过程 1 1 人脸检测 1 2 人脸对齐 1 3 人脸特征向量化 1 4 人脸识别 2 深度学习 人脸识别过程 2 1 人脸检测 2 2 人脸识别 3 最后 0 前言 Hi 大家好 这里是丹成学长的
  • 2013年4月10日星期三 (DEMO7——6使用blitter)

    本来打算晚上进行封装 不过由于上午进行HDR 只剩下RENDERBLOOM 了 有些疲倦 不妨先进行封装 闲话少说 现在是14 18 开始进行了 这1节还是开头强调了硬件局限性 目前当然没有这个问题了 只考虑封装方法吧 大概浏览了一下这一节
  • 0.0.0.0 网关的含义

    简介 使用 route 命令查看linux的路由时候常遇到 gateway为0 0 0 0 的情况 注意不是目标网段 让人很困惑 仔细看看这些网卡往往时候一些虚拟出来的网卡 比如docker0 0 0 0 0 或者 表示不需要路由 目标地址
  • Addressables学习笔记3: 实际操作实现资源热更新

    本篇基本上是官方演示的东西 介绍一下如何快速使用Addressables实现资源热更 为了能够热更资源 你需要有一个资源服务器使你能下载资源 一 资源准备 首先打开Unity编辑器菜单 gt Window gt Asset Manageme
  • 通用工具类

    package com struts2 jquery utils import java io File import java io IOException import java io OutputStream import java
  • 驱动级鼠标模拟实现_S71500PLC 连接 V90 伺服系统实现位置闭环控制

    S7 1500 运动控制功能支持旋转轴 定位轴 同步轴和外部编码器等工艺对象 并拥有轴控制面板以及全面的在线和诊断功能有助于轻松完成驱动装置的调试和优化工作 S7 1500 支持多种连接方式 可以使用 PROFIBUS DP 和 PROFI
  • Android缓存机制&一个缓存框架推荐

    1 先推荐一个轻量级缓存框架 ACache ASimpleCache ACache介绍 ACache类似于SharedPreferences 但是比 SharedPreferences功能更加强大 SharedPreferences只能保存
  • yagmail群发邮件

    直接给代码 导入yagmail第三方库 import yagmail yagmail SMTP user 邮箱名 host SMTP服务器域名 yag yagmail SMTP user 284036658 qq com host smtp
  • 零信任提升组织的数字安全性

    组织越来越多地实施零信任策略以增强其数字安全状况 根据 信息安全杂志 的统计 有15 的组织表示他们在2019年底之前实施了零信任策略 另有59 的参与者表示 他们打算在未来12个月内实施 要了解为什么如此众多的组织涌向零信任 首先要深入了
  • 性能测试工具---JMeter的安装与使用详解(第一篇)

    目录 一 主流性能测试工具 1 1 LoaderRunner 1 2 JMeter 二 JMeter环境搭建 2 1下载安装JDK 2 2 下载安装JMeter 2 3 JMeter文件目录介绍 2 3 1 bin目录 2 3 2 docs
  • python 写文件 换行_python中写入txt文件需要换行,以及\r 和\n

    在Python中 用open 函数打开一个txt文件 写入一行数据之后需要一个换行 如果直接用 f write n 只会在后面打印一个字符串 n 而不是换行 需要用 f write r n 注意点 1 python文件写入的时候 当写入一段
  • 【SpringBoot学习】05-自定义LocaleResolver国际化区域语言

    首先配置好i18n文件 以及所对应的语言 在properties中配置 因为默认为 message spring messages basename i18n xxxx 页面内容替换 配置点击 配置一个 LocaleResolver 自定义
  • 十种常用机器学习算法入门

    弱人工智能近几年取得了重大突破 悄然间 已经成为每个人生活中必不可少的一部分 以我们的智能手机为例 看看到底温藏着多少人工智能的神奇魔术 下图是一部典型的智能手机上安装的一些常见应用程序 可能很多人都猜不到 人工智能技术已经是手机上很多应用
  • 【Linux】动静态库

    文章目录 1 动静态库的原理 2 动态库和静态库基础 3 动静态库的实现 3 1设计一个静态库 3 2设计一个动态库 4 动静态库的使用 4 1静态库的使用 4 2动态库的使用 4 3动态库的多进程共享原理 1 动静态库的原理 源文件和头文