Linux:动静态库
1.库是什么,作用是什么
库是写好的,现有的可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存中执行。库有两种:
静态库后缀 .a (在linux下) .lib (在windows下)
动态库后缀 .so (在linux下) .dll (在windows下)
静态库
静态库 (.a):程序在编译链接的时候把库里的代码链接到可执行文件中链接完后,静态库的代码就成为了目标文件的一部分,如果多个程序使用同一个静态库,那么每个程序都会包含一份该库的副本,从而导致程序体积较大。然后程序运行的时候不再需要静态库了。
优点:
独立性高
静态库在编译时直接嵌入到可执行文件中,程序运行时无需依赖外部库文件,减少了部署时的依赖问题。执行效率高
代码在编译时已完全链接,运行时无需加载外部库,启动速度和执行效率通常更快。部署简单
可执行文件是独立的,无需额外分发或配置库文件,适合嵌入式系统或封闭环境。兼容性问题少
无需担心库版本与系统环境不匹配的问题。缺点:
文件体积大
每个可执行文件都包含库代码的副本,占用更多磁盘和内存空间(尤其是多个程序使用同一库时)。更新困难
库的更新需要重新编译整个程序,维护成本高,无法快速修复漏洞。内存冗余
多个程序运行时,相同库代码的多个副本会重复占用内存。
动态库
动态库(.so):程序运行时才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码,在运行前,外部函数的机器码有操作系统从磁盘上的该动态库中赋值到内存中,这个过程叫做动态链接。
动态库可以在多个程序间共享,所以动态链接使可执行文件更小,节省了磁盘空间。操作系统通过虚拟内存机制 允许物理内存中的一份动态库被所有用到该库的进程共用,节省内存和磁盘空间。
优点:
节省资源
多个程序共享同一动态库文件,减少磁盘和内存占用。更新便捷
替换动态库文件即可更新功能或修复漏洞,无需重新编译程序。支持运行时加载
可实现插件机制或延迟加载,灵活扩展程序功能。编译效率高
链接时仅记录引用,编译速度较快(尤其是大型项目)。缺点:
依赖管理复杂
程序运行时需确保系统中存在正确版本的动态库,否则会崩溃(如“DLL地狱”)。性能略低
首次加载库时需要额外开销,可能影响启动速度。兼容性风险
若动态库接口或行为变更,可能导致依赖它的程序异常(需严格版本控制)。部署稍复杂
需确保目标环境已安装所需动态库,或与程序一起分发。
2.动静态库的原理
一个源文件变为一个可执行文件需要四个步骤:
1.预处理:完成头文件展开、去注释、宏替换、条件编译等、最终形成xxx.i文件。
2.编译:完成词法分析、语法分析、语义分析、符号汇总等。检查后将代码翻译成汇编指令,最终形成xxx.s文件
3.汇编:将汇编指令变为二进制指令、最终形成xxx.o文件。
4.链接:将形成的各个xxx.o文件进行链接最终形成可执行程序。

我们将形成的.o文件打包起来。之后只需要链接这个包即可。这个包就是我们常说的库。
动静态库本质上就是一堆.o文件的集合。使用库只需要提供头文件给使用者。在编译程序时,通过链接指定的库来实现对库中功能的调用。
3.动静态库的打包
四个文件分别是:
add.c
#include"add.h"
int add(int x,int y)
{return x+y;
}
add.h
#pragma once int add(int x,int y);
get_m.c
#include"get_m.h"
int get_m(int a,int b)//return a的b次方
{int t=1;while(b){ if(b&1)//是奇数{ t+=a;//} a=a*a;//自身的平方b=b>>1;//} return t;
}
get_m.h
#pragma onceint get_m(int a,int b);
静态库的打包
1.然后将这些.c文件生成.o文件
![]()
2.使用ar指令打包成对应的静态库。
使用格式:
ar 选项 库名 打包文件名
关键的两个选项:
-r(replace): 如果静态库文件当中的目标文件有更新,则用新的目标文件替换就得目标文件
-c(create): 建立静态库文件

3.将头文件和生成的静态库组织起来。
把自己的库提供给他人使用时,通常需要给予两个文件夹:
一个文件夹存放头文件集合。即把所有的.h头文件放到一个目录下
一个文件夹存放所有的库文件。即把生成的.a文件存放到一个目录

4.使用静态库
我们使用自己打包的静态库在使用gcc进行编译时要有以下三个选项:
- -I(大写的i):指定头文件搜索路径。
- -L:指定库文件搜索路径
- -l(小写的L):指明文件需要链接库文件路径下的哪一个库(注意,libmath.a 我们只需-lmath即可 不需要加上lib 和 .a)
我们在命令行中指定头文件的搜索路径,库文件的搜索路径以及具体使用哪个库

例如我们要执行main.c,这个.c文件里使用了静态库中的两个函数。
#include<stdio.h>
#include"add.h"
#include"get_m.h" int main()
{int a=2;int b=20;int res=add(a,b);int sum=get_m(a,b);printf("%d\n",res);printf("%d\n",sum);return 0;
}

上面三个选项都可以选的加空格和不加空格。
我们平时使用gcc之所以没带上这个三个选项是因为,我们之前使用的库都默认在系统路径下,编译器能准确识别这些存在于配置文件的路径,如果我们将头文件和库文件拷贝到系统路径 /usr/include/lib.64 下
- sudo cp libmath/include/* /usr/include/
- sudo cp libmath/lib/* /lib.64/
这样只需要带 -l(小写的L) 指明链接库文件下具体哪个库。
但是不推荐这么做可能会污染系统文件。
动态库的打包
1.生成.o文件
区别于静态库需要加上 -fPIC选项(I为大写的i) 。
-fPIC是一个非常重要的编译选项。它的作用是生成 位置无关代码
位置无关代码是一种特殊的代码,它可以在内存中的任何位置运行,而不需要修改代码本身。
动态库(共享库)会被多个程序共享,并且在运行时加载到内存中。由于无法预知动态库会被加载到内存的哪个位置,因此必须使用位置无关代码来确保动态库的正确运行。
为什么要使用?
动态库在编译时无法确定其加载的内存地址,因此必须使用位置无关代码。
如果不使用
-fPIC,编译生成的代码可能会包含绝对地址,导致动态库在加载时无法正确运行。使用
-fPIC可以确保动态库在内存中的任何位置都能正常运行。

2. 打包为动态库,-shared选项
生成动态库不需要ar指令,使用gcc编译加上-shared选项 (shared意为共享)。

3.将头文件和生成的动态库组织起来
将自己的库提供给他人使用时,与静态库一样通常给予两个文件:
将两个头文件放到一个目录 includeso中
生成的动态库文件libmath.so放到libso目录中
![]()
4. 动态库的使用
与静态库一样使用gcc编译带上三个选项
- -I(大写的i):指定头文件搜索路径。
- -L:指定库文件搜索路径
- -l(小写的L):指明文件需要链接库文件路径下的哪一个库(注意,libmath.a 我们只需-lmath即可 不需要加上lib 和 .a)
指定头文件的搜索路径,库文件的搜索路径以及具体使用哪个库。
依然是使用加法和快速幂函数
#include<stdio.h>
#include"add.h"
#include"get_m.h" int main()
{int a=2;int b=20;int res=add(a,b);int sum=get_m(a,b);printf("%d\n",res);printf("%d\n",sum);return 0;
}

但是这个a.out 不能直接执行。
即使使用了-I -L -l 依然没找到对应的动态库?
因为这三个选项只是在编译期间向编译器告知我们所使用的头文件和库文件的具体位置以及具体的库名。当可执行程序生成后就不再与编译器有直接的关系了,所以依然找不到此程序所依赖的动态库。
为了解决这个问题
(1).将库文件拷贝到系统共享的库路径下
sudo cp ./lib/libmath.so /lib64但是与上面的静态库一样可能会对系统文件造成污染,一般不使用此方法。
(2).在系统共享路径建立同名软链接
sudo ln -s /home/pc/linuxplusplus/test39/libso/libmath.so /usr/lib/libmath.so(3).更改环境变量 LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pc/linuxplusplus/test39/libso//(自己对应动态库所在路径)LD_LIBRARY_PATH是程序运行动态查找库时所要搜索的路径,我们只需要将动态库所在目录路径添加到LD_LIBRARY_PATH环境变量中,程序运行起来就能找到对应的路径下的动态库。但是环境变量会在重启时自动重置,所以这种方法具有临时性。
(4)/etc/ld.so.conf.d/
在系统中/etc/ld.so.conf.d/是用于搜索动态库的路径,此路径下存放的全是后缀为.conf的配置文件,这些配置文件中所存放的都是动态库的路径。
所以将自己的库文件也放在这路径下,在可执行程序运行时,系统就可以找到我们的库文件。这种行为是永久的,不会因为重启改变。
将对应库文件地址写入一个.conf 文件中,然后将其导入/etc/ld.so.conf.d/路径,使用ldconfig指令更新以下配置文件,就可以执行可执行文件了

4.动静态库的使用

ldd 文件名 可以查看一个可执行程序所依赖的库文件,上面的libc.so.6就是该可执行程序所依赖的库文件,实际是一个软链接,这个软链接的原文件 libc-2.31.so 和libc.so.6在同一个目录下。
gcc与g++编译器默认都是动态链接的,如果非要静态链接,就只能在后面 -static 一旦 -static就必须存在相应的静态库。没有安装可以使用下面指令进行安装
centOS下sudo yum install glibc-static
sudo yum install libstdc++-staticunbento下sudo apt install glibc-static
sudo apt install libstdc++-static
这篇就到这里啦再见(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤
相关文章:
Linux:动静态库
1.库是什么,作用是什么 库是写好的,现有的可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始。 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存中执行。库有两种&#…...
鸿蒙跨平台框架ArkUI-X
01 引言 目前,移动端主流跨平台方案有Flutter、React Native、uni-app等等,还有刚推出不久的Compose-Multiplatform,真所谓是百花齐放。这些框架各有特点,技术实现各有差异,比如Flutter通过Dart编写的UI描述对接Flutte…...
第7章 wireshark(网络安全防御实战--蓝军武器库)
网络安全防御实战--蓝军武器库是2020年出版的,已经过去3年时间了,最近利用闲暇时间,抓紧吸收,总的来说,第7章开始学习抓包工具wireshark,如果你怀疑自己的电脑中毒了,那么用wireshark可以很轻松…...
【AI】神经网络|机器学习——图解Transformer(完整版)
Transformer是一种基于注意力机制的序列模型,最初由Google的研究团队提出并应用于机器翻译任务。与传统的循环神经网络(RNN)和卷积神经网络(CNN)不同,Transformer仅使用自注意力机制(self-attention)来处理输入序列和输出序列,因此可以并行计算,极大地提高了计算效率…...
002-SpringCloud-OpenFeign(远程调用)
SpringCloud-OpenFeign 1.引入依赖2.编写一个远程调用接口3.测试 1.引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> </dependency><dependencyManageme…...
基于类型的声明接收props
在 Vue 3 中,除了运行时声明这种常见方式,还可以通过基于类型的声明、解构赋值等方式来接收 props,下面为你详细介绍: 1. 基于类型的声明 这种方式借助 TypeScript 的类型系统来定义 props,具有类型检查和代码提示的…...
多方安全计算(MPC)电子拍卖系统
目录 一、前言二、多方安全计算(MPC)与电子拍卖系统概述2.1 多方安全计算(MPC)的基本概念2.2 电子拍卖系统背景与需求三、MPC电子拍卖系统设计原理3.1 系统总体架构3.2 电子拍卖中的安全协议3.3 数学与算法证明四、数据加解密模块设计五、GPU加速与系统性能优化六、GUI设计与系…...
使用QT + 文件IO + 鼠标拖拽事件 + 线程 ,实现大文件的传输
第一题、使用qss,通过线程,使进度条自己动起来 mythread.h #ifndef MYTHREAD_H #define MYTHREAD_H#include <QObject> #include <QThread> #include <QDebug>class mythread : public QThread {Q_OBJECT public:mythread(QObject* …...
【无人机路径规划】基于麻雀搜索算法(SSA)的无人机路径规划(Matlab)
效果一览 代码获取私信博主基于麻雀搜索算法(SSA)的无人机路径规划(Matlab) 一、算法背景与核心思想 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种受麻雀群体觅食行为启发的元启发式算法࿰…...
基于物联网技术的分布式光伏监控系统设计与实现
一、分布式光伏发电系统标准规范 1.常见应用场景 2.并网标准 Q/GDW1480-2015《分布式电源接入电网技术规定》 分布式电源并网电压等级可根据各并网点装机容量进行初步选择,推荐如下: 8kW 及以下可接入220V; 8kW~400kW可接入380V…...
阿里发布新开源视频生成模型Wan-Video,支持文生图和图生图,最低6G就能跑,ComFyUI可用!
Wan-Video 模型介绍:包括 Wan-Video-1.3B-T2V 和 Wan-Video-14B-T2V 两个版本,分别支持文本到视频(T2V)和图像到视频(I2V)生成。14B 版本需要更高的 VRAM 配置。 Wan2.1 是一套全面开放的视频基础模型&…...
27. Harmonyos Next仿uv-ui 组件NumberBox 步进器组件禁用状态
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! 文章目录 1. 组件介绍2. 效果展示3. 禁用状态设置3.1 整体禁用3.2 输入框禁用3.3 长按禁用 4. 完整示例代码5. 知识点讲解5.1 禁用状态属性5.2 禁用…...
【软件工程】一篇入门UML建模图(状态图、活动图、构件图、部署图)
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀软件开发必练内功_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…...
AI智能导航站HTML5自适应源码帝国cms7.5模板
源码名称:AI导航站HTML5自适应源码帝国cms7.5模板 开发环境:帝国cms 7.5 安装环境:phpmysql var code "4d33ef8e-9e38-43b9-b37b-38f75944ecc9" 带软件采集,可以挂着自动采集发布,无需人工操作࿰…...
Redis 发布订阅模式详解:实现高效的消息通信
目录 引言 1. 什么是 Redis 发布订阅模式? 1.1 定义 1.2 核心概念 2. Redis 发布订阅的工作原理 2.1 基本流程 2.2 示例 2.3 频道与模式订阅 3. Redis 发布订阅的使用场景 3.1 实时消息通知 3.2 事件驱动架构 3.3 日志收集与分发 3.4 分布式锁与协调 4…...
ES的预置分词器
Elasticsearch(简称 ES)提供了多种预置的分词器(Analyzer),用于对文本进行分词处理。分词器通常由字符过滤器(Character Filters)、分词器(Tokenizer)和词元过滤器&#…...
MPPT与PWM充电原理及区别详解
MPPT(最大功率点跟踪)和PWM(脉宽调制)是太阳能充电控制器中常用的两种技术,它们在原理、效率和适用场景上有显著区别。以下是两者的详细对比: 1. 工作原理 PWM(脉宽调制) 核心机制…...
【AGI】通往AGI的复兴号:模型工具演进与技术路径优化
通往AGI的复兴号:模型工具演进与技术路径优化 一、核心模型与工具技术指标及场景分析1. 边缘计算标杆:GLM-PC(2024年11月)2. 长文本处理王者:DeepSeek R1(2025年1月)3. 轻量化开源代表ÿ…...
java2025年常见设计模式面试题
1. 请解释建造者模式(Builder Pattern)及其应用场景。 答案: 建造者模式用于创建一个复杂的对象,同时允许用户只通过指定复杂对象的类型和内容就能构建它们,隐藏了复杂的构建逻辑。 示例: public class C…...
探索CAMEL:揭开多智能体系统的神秘面纱
在人工智能领域,多智能体系统(Multi-Agent Systems, MAS)一直是一个充满活力和潜力的研究方向。随着大语言模型(LLM)的快速发展,智能体之间的协作与交互变得更加复杂和智能。今天,我们要介绍的是一个名为CAMEL(Communicative Agents for “Mind” Exploration of Large…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
