[Linux]动静态库
[Linux]动静态库
文章目录
- [Linux]动静态库
- 见一见库
- 存在库的原因
- 编写库
- 模拟编写静态库
- 模拟使用静态库
- 模拟编写动态库
- 模拟使用静态库
- 库的加载原理
- 静态库的加载原理
- 动态库的加载原理
- 库在可执行程序中的编址策略
- 静态库在可执行程序中的编址策略
- 动态库在可执行程序中的编址策略
见一见库
在Linux系统中,C语言标准库(C Standard Library)和其他常用库都被称为C库(C library),通常存放在/usr/lib或/usr/lib64目录下:

在Linux系统中,/usr/include目录下存放了许多头文件:

- Linux系统预装了C/C++的头文件和库文件,头文件提供方法的说明,库文件提供方法的实现,头文件和库文件有对应关系,需要组合使用。
- 在程序编译形成可执行程序的过程中,头文件在预处理时被引入,库文件在链接时被链接 。
- 在visual studio下安装开发环境时,不仅安装了编译器软件,还安装语言对应的头文件和库文件。
- 编译器会自动根据用户的输入,查找头文件中的相关内容,实现语法提示的功能。
- 编译器会自动根据用户的输入,不断地进行编译,实现语法报错的功能。
存在库的原因
编程语言将常用的功能添加到库中,以便于用户可以直接使用这些功能,提高开发的效率。比如printf,用户不需要在每次想打印数据时,编写一个用于打印数据的函数。
编写库
模拟编写静态库
进行库的编写前要说明一下:
- 库分为动态库和静态库
- Linux下静态库的命名规则:
lib库名.a - Linux下动态库的命名规则:
lib库名.so - 云服务下一般不会内置静态库
- 头文件和源文件的编写
编写头文件myadd.h和其对应的源文件myadd.c和头文件mysub.h和其对应的源文件mysub.c,各文件中的具体代码如下:
//myadd.h
#pragma once int my_add(int x, int y);//myadd.c
#include "myadd.h" int my_add(int x, int y)//一个简单的加法函数
{return x + y;
}
//mysub.h
#pragma once int my_sub(int x, int y);//mysub.c
#include "mysub.h" int my_sub(int x, int y)//一个简单的减法函数
{return x - y;
}
- 将源文件编译成目标文件
使用gcc -c 源文件名将源文件编译成目标文件:

- 打包成静态库
使用ar -rc lib库名.a 目标文件 将目标文件打包成静态库:

- 模拟库文件目录结构
创建include目录将头文件移动到该目录中,创建lib目录将静态库移动到该目录中:

- 将库打包成压缩包
使用tar -czf 目标压缩包名 源文件将库打包成压缩包:

模拟使用静态库
- 将前文操作中打包好的静态库压缩包复制到某一目录下并解压来模拟库的下载过程

- 在当前目录下创建源文件main.c并编写调用静态库的代码,具体代码实现如下:
#include <stdio.h>
#include "myadd.h"
#include "mysub.h"int main()
{int x = 20;int y = 10;printf("%d + %d = %d\n", x, y, my_add(x, y));printf("%d - %d = %d\n", x, y, my_sub(x, y));return 0;
}
- 将源文件main.c编译形成可执行程序:

由于第三方头文件不在编译的目录下,需要-I 路径选项指明头文件路径,由于第三方库编译器不会自己查找和使用,需要-L 路径指明库文件路径名,需要-l 库名指明库名。
总结一下Linux系统下第三方库的使用:
- 需要指定头文件路径和库文件的路径和名称
- 如果没有将头文件和库文件安装到编译器搜素的默认路径下,用户必须指明对应选项:
- 头文件路径 (
-I 路径) - 库文件路径(
-L 路径) - 库名(
-l 库名)
- 头文件路径 (
- 安装头文件和库文件的本质是将文件拷贝至系统默认路径下。
- 头文件和库文件安装后,编译时需要指明库名选项
模拟编写动态库
在模拟编写动态库时,沿用了前文中打包静态库使用的头文件myadd.h和其对应的源文件myadd.c和头文件mysub.h和其对应的源文件mysub.c。
- 将源文件进行编译
打包动态库时需要使用gcc -fPIC -c 源文件名将源文件编译成目标文件:

- 将目标文件打包成动态库
使用gcc -shared -o lib库名.so 目标文件将目标文件打包成动态库:

- 模拟库文件目录结构
创建include目录将头文件移动到该目录中,创建lib目录将静态库移动到该目录中:

- 将库打包成压缩包
使用tar -czf 目标压缩包名 源文件将库打包成压缩包:

模拟使用静态库
- 将前文操作中打包好的动态库压缩包复制到某一目录下并解压来模拟库的下载过程

- 在当前目录下创建源文件main.c并编写调用静态库的代码,具体代码实现如下:
#include <stdio.h>
#include "myadd.h"
#include "mysub.h"int main()
{int x = 20;int y = 10;printf("%d + %d = %d\n", x, y, my_add(x, y));printf("%d - %d = %d\n", x, y, my_sub(x, y));return 0;
}
- 将源文件main.c编译形成可执行程序:
指定动态库头文件的路径、库文件的路径和库名后,编译器能够成功编译,由于是动态库,程序运行时需要OS根据程序内的动态库地址链接到动态库才能成功运行,但是OS无法找到该动态库,就造成了下图的情况:

- 采用导入环境变量的方式使得程序运行(临时方案)
使用export LD_LIBRARY_PATH=LD_LIBRARAY_PATH:动态库所在目录路径将动态库路径导入环境变量,OS在运行程序时会从环境变量中的路径找到动态库并成功运行:

解决第三方动态库OS查找不到的方法:
- 导入环境变量:使用
export LD_LIBRARY_PATH=LD_LIBRARAY_PATH:动态库所在目录路径将动态库路径导入环境变量,环境变量会在重新打开shell时重新加载,因此是临时方案 - 在系统路径下建立动态库的软链接:使用
sudo ln -s 动态库路径 /lib64/lib库名.so将动态库的软链接添加到系统路径下 - 修改配置文件:在
/etc/ld.so.conf.d/路径下创建后缀为.conf文件,将静态库的路径写入该文件,然后使用sudo ldconfig使配置文件生效。
库的加载原理
静态库的加载原理
动态库的加载过程就是在形成可执行程序的链接过程中直接将静态库中的实现拷贝至可执行程序中。因此静态库十分占用资源(磁盘、内存、网络资源)。

动态库的加载原理
首先,使用动态库生成可执行程序时,在链接过程中,可执行程序中只会将代表库中方法的外部符号替换成对应地址,由于形成可执行程序中没有具体的实现,因此要想运行起来,操作系统做了一系列的工作,在程序被加载到内存中形成进程后,操作系统会为其维护进程控制块和进程地址空间和页表等:

在进程运行到动态库中的方法后,操作系统会在页表中寻找映射,发现映射到内存中的只是一个对应地址而不是具体方法实现,因此操作系统寻找这个动态库,按照一定策略将动态库加载到内存中,然后操作系统会将加载到内存中的动态库映射给进程地址空间中在栈区和堆区之间的共享区:

而后,每次该进程执行该库中方法时,只需要跳转到进程地址空间中的共享区,就可以完成程序的执行:

另外,当该库被加载到内存中后,后续运行的进程需要执行该库方法时,不需要再在内存中加载库,而是直接创建共享区映射,然后使用库中方法。
库在可执行程序中的编址策略
静态库在可执行程序中的编址策略
形成可执行程序时,可执行程序中会存在逻辑地址,如果采用的是静态库,可执行程序中静态库的方法也会被编址,获得一个逻辑地址,在程序变成进程运行时,只需要根据逻辑地址进行跳转即可。
动态库在可执行程序中的编址策略
形成可执行程序时,可执行程序中会存在逻辑地址,如果采用的是动态库,可执行程序中动态库的方法也会被编址,但该地址是库中方法在库中从起始地址开始的偏移量,在制作动态库的获取目标文件的操作时,使用gcc添加-fPIC就是获取这个被称为与地址无关码的地址偏移量,在实际进程运行时,进程只需要等待库中方法被加载到内存中并被映射到共享区,然后利用共享区映射加上偏移地址完成运行。
说明一下:
- gcc/g++编译器编译形成可执行程序时,默认使用动态库。
- gcc/g++编译器编译形成可执行程序时,使用
-static选项,将使用静态库。 - gcc/g++编译器编译形成可执行程序时,部分动态库不存在,会采用动态库混合使用的方式。
相关文章:
[Linux]动静态库
[Linux]动静态库 文章目录 [Linux]动静态库见一见库存在库的原因编写库模拟编写静态库模拟使用静态库模拟编写动态库模拟使用静态库 库的加载原理静态库的加载原理动态库的加载原理 库在可执行程序中的编址策略静态库在可执行程序中的编址策略动态库在可执行程序中的编址策略 见…...
2023高教社杯数学建模国赛C题思路解析+代码+论文
如下为C君的2023高教社杯全国大学生数学建模竞赛C题思路分析代码论文 C题蔬菜类商品的自动定价与补货决策 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此&…...
macos13 arm芯片(m2) 搭建hbase docker容器 并用flink通过自定义richSinkFunction写入数据到hbase
搭建hbase docker容器 下载镜像 https://hub.docker.com/r/satoshiyamamoto/hbase/tags 点击run 使用镜像新建容器 填写容器名和 容器与宿主机的端口映射 测试 通过宿主机访问容器内的hbase webUI http://localhost:60010/master-status...
FLV封装格式
摘要:本文描述了FLV的文件格式。 关键字:FLV 1 简介 FLV流媒体格式是sorenson公司开发的一种视频格式,全称为Flash Video。 它的出现有效地解决了视频文件导入Flash后,使导出的SWF文件体积庞大,不能在网络上很好的…...
[NLP]LLM---FineTune自己的Llama2模型
一 数据集准备 Let’s talk a bit about the parameters we can tune here. First, we want to load a llama-2-7b-hf model and train it on the mlabonne/guanaco-llama2-1k (1,000 samples), which will produce our fine-tuned model llama-2-7b-miniguanaco. If you’re …...
git在linux情况下设置git 命令高亮
只需要执行下面这个命令,这样就可以在查看git status明亮的时候高亮显示。 git config --global color.status auto未设置前 谁知之后...
C++ 表驱动方法代替if-else
连着用几十个if-else代码,运行效率不高,关键还手累,记得改成表驱动方法 #include <iostream> #include <unordered_map> #include <functional>using namespace std;void handleCondition1() {// 处理条件 1 的代码std::cout <<…...
2023国赛数学建模E题思路分析 - 黄河水沙监测数据分析
# 1 赛题 E 题 黄河水沙监测数据分析 黄河是中华民族的母亲河。研究黄河水沙通量的变化规律对沿黄流域的环境治理、气候变 化和人民生活的影响, 以及对优化黄河流域水资源分配、协调人地关系、调水调沙、防洪减灾 等方面都具有重要的理论指导意义。 附件 1 给出了位…...
cadence后仿真/寄生参数提取/解决pin口提取不全的问题
post-simulation设置顺序与规则 1.Rules 设置 2.inputs设置 3.outputs设置 4.PEX 设置 会出现错误1,后有解决方案 第一步 :Netlist 第二步:LVS 5.RUN PEX 先RUN,后按照图中1 2 3步骤操作 点击OK之后,显示Calibre信息ÿ…...
Vue中实现3D得球自动旋转
具体实现 安装echarts 在终端下安装echarts npm install -D echarts 安装echarts-gl 在终端下安装echarts-gl npm install -D echarts-gl earth3D组件 earth3D.vue <template><div class"globe3d-earth-container" ><div class"globe3d-earth&qu…...
使用wkhtmltoimage实现生成长图分享
需求 用户可以选择以长图的形式分享本网页 方法 wkhtmltopdf wkhtmltopdf url filewkhtmltoimage url file java Runtime.getRuntime().exec() 下载 直接去官网下载对应的版本:官网 命令行使用WK > wkhtmltopdf https://www.nowcoder.com /opt/project/…...
新风机未来什么样?
新风机在未来将会有许多令人期待的发展和改进,让我们一起来看一看吧!以下是新风机未来的一些可能性: 智能化和智能家居:新风机将更多地与智能家居系统整合,通过物联网和人工智能技术,实现智能控制和智能调节…...
python的几种数据类型的花样玩法(一)
Python是一种动态类型语言,这意味着在Python中,你可以操作多种不同的数据类型,而且这些数据类型可以自动转换。以下是一些Python数据类型的花样玩法: 数字: 整数 (1, 100, -786 等) 浮点数 (1.1, -78.4, 3.14159 等)…...
python回调函数之获取jenkins构建结果
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 需求背景: 现在用jenkins构建自动化测试(2个job),公司现将自动化纳入到发布系统 要求每次构建成功之后&am…...
Docker底层实现
Docker采用c/s架构,Docker守护进程( Daemon )作为服务端,接受来自客户端(命令行)的请求,并处理这些请求(创建、运行、分发容器) 。客户端和服务端既可以运行在一个机器上…...
PY32F003F18之RS485通讯
PY32F003F18将USART2连接到RS485芯片,和其它RS485设备实现串口接收后再转发的功能。 一、测试电路 二、测试程序 #include "USART2.h" #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf() #include "…...
概率论与数理统计学习笔记(7)——全概率公式与贝叶斯公式
目录 1. 背景2. 全概率公式3. 贝叶斯公式 1. 背景 下图是本文的背景内容,小B休闲时间有80%的概率玩手机游戏,有20%的概率玩电脑游戏。这两个游戏都有抽卡环节,其中手游抽到金卡的概率为5%,端游抽到金卡的概率为15%。已知小B这天抽…...
深入了解 Axios 的 put 请求:使用技巧与最佳实践
在前端开发中,我们经常需要与后端服务器进行数据交互。其中,PUT 请求是一种常用的方法,用于向服务器发送更新或修改数据的请求。通过发送 PUT 请求,我们可以更新服务器上的资源状态。 Axios 是一个流行的 JavaScript 库࿰…...
浅谈Http协议、TCP协议(转载)
TCP标志位,有6种标示:SYN(synchronous建立联机) ,ACK(acknowledgement 确认) ,PSH(push传送),FIN(finish结束) ,RST(reset重置), URG(urgent紧急) Sequence number(顺序号码) ,Acknowledge num…...
flatten-maven-plugin使用
这篇文章主要介绍了flatten-maven-plugin使用,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 − 目录 一、简介 1.1 作用1.2 goal介绍二、使用总结 一、简介 1.1 作用 将pom工程父子pom的版…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
