linux入门到精通-第五章-动态库和静态库
目录
- 参考
 - 概述
 - 1、静态链接
 - 2 、动态链接
 - 3 、静态、动态编译对比
 
- 静态库和动态库简介
 - 传统编译
 
- 静态库制作和使用
 - 1、创建静态库的过程
 - 2、使用静态库
 
- 动态库制作和使用
 - 1、创建动态库的过程
 - 1)、生成目标文件,此时要加编译选项:-fPIC (fpic)
 - 2)、 生成共享库,此时要加链接器选项:-shared (指定生成动态链接库)
 - 3)、通过nm命令查看对应的函数
 
- 2、使用动态库
 - 编译执行文件
 - 通过ldd命令查看可执行问价噢爱你依赖的动态库
 - 执行
 - 让系统找到动态库
 
参考
动态库和静态库
概述
链接分为两种:静态链接、动态链接
1、静态链接
静态链接: 由链接器在链接时将库的内容加入到可执行程序中
 优点:
- 对运行环境的依赖性较小,具有较好的兼容性
 
缺点:
- 生成的程序比较大,需要更多的系统资源,在装入内存时会消耗更多的时间
 - 库函数有了更新,必须重新编译应用程序
 
2 、动态链接
动态链接: 连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序。
 优点:
- 在需要的时候才会调入对应的资源函数
 - 简化程序的升级;有着较小的程序体积
 - 实现进程之间的资源共享(避免重复拷贝)
 
缺点:
- 依赖动态库,不能独立运行
 - 动态库依赖版本问题严重
 
3 、静态、动态编译对比
前面我们编写的应用程序大量用到了标准库函数,系统默认采用动态链接的方式进行编译程序,若想采用静态编译,加入-static参数
 以下是分别采用动态编译、静态编译时文件对比
 测试程序(test.c)如下:
#include <stdio.h>
int main(void)
{printf("he11o world n");return 0;
}
 
编译:
# 动态库
deng@itcast:-/test$ gcc test.c -o test share
# 静态库
deng@itcast:-/test$ gcc -static test.c -o test_static
 
结果对比:
 
静态库和动态库简介
所谓“程序库”,简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其他执行程序的一部分来完成模型功能。
 库的存在可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。
 程序库可分入静态库(static library)和共享库(shared library)。
传统编译
定义add.h
#ifndef __ADD_H__
#define __ADD_H__int add(int x, int y);#endif /*__ADD_H__*/
 
定义add.c
#include "add.h"int add(int x, int y) {return x + y;}
 
定义sub.h
#ifndef __SUB_H__
#define __SUB_H__int sub(int x, int y);#endif /*__SUB_H__*/
 
sub.c
#include "sub.h"int sub(int x, int y) {return x - y;}
 
定义测试程序test.c
#include <stdio.h>
#include "add.h"
#include "sub.h"int main(void)
{int x = 15;int y = 5;printf("x + y = %d\n", add(x, y));printf("x - y = %d\n", sub(x, y));return 0;
} 
编译运行
### 编译
```bash
gcc add.c sub.c test.c
# 或者
gcc *.c
 
执行
./a.out
 
静态库制作和使用
静态库可以认为是一些目标代码的集合,是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分。按照习惯一般以”.a”做为文件后缀名。静态库的命名一般分为三个部分:
- 前缀: lib
 - 库名称:自己定义即可
 - 后缀:.a
所以最终的静态库的名字应该为: libxxx.a 
1、创建静态库的过程

- 步骤1: 将c源文件生成对应的.o文件
 
deng@itcast:-/test/3static_lib$ gcc -c add.c -o add.o
deng@itcast:-/test/3static_lib$ gcc -c sub.c -o sub.o
deng@itcast:-/test/3static_lib$ gcc -c mul.c -o mul.o
deng@itcast:-/test/3static_lib$ gcc -c div.c -o div.o
 
- 步骤2: 使用打包工具ar将准备好的.o文件打包为.a文件 libtest.a
 
deng@itcast:-/test/3static lib$ ar -rcs libtest.a add.o sub.o mulo div.o
 
在使用ar工具是时候需要添加参数: rcs
- r 更新
 - c 创建
 - s 建立索引
 
2、使用静态库
静态库制作完成之后,需要将.a文件和头文件一起发布给用户。
 假设测试文件为main.c,静态库文件为libtest.a头文件为head.h编译命令:
deng@itcast:-/test/4static$ gcc test.c -I./ -L./ -ltest -o test 
参数说明:
- -I: 表示要连接的库的头文件所在目录
 - -L:表示要连接的库所在目录
 - -I(小写L):指定链接时需要的库,去掉前缀和后缀
 

动态库制作和使用
共享库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规辟了空间浪费问题
 动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署和发布也会带来麻烦。用户只需要更新动态库,增量更新。
 按照习惯,一般以“.so”做为文件后缀名。共享库的命名般分为三个部分
- 前缀: lib
 - 库名称: 自己定义即可
 - 后缀: .so
所以最终的动态库的名字应该为: libxxx.so 

1、创建动态库的过程
1)、生成目标文件,此时要加编译选项:-fPIC (fpic)
gcc -fPIC -c add.c
gcc -fPIC -c sub.c 
参数: -fPIC 创建与地址无关的编译程序 (pic,position independent code) ,是为了能够在多个应用程序间共享。
2)、 生成共享库,此时要加链接器选项:-shared (指定生成动态链接库)
gcc -shared add.o sub.o -o libtest.so 
3)、通过nm命令查看对应的函数
root@sony-HP-Notebook:/usr/local/cpp_demo/library#  nm libtest.so | grep add
00000000000010f9 T add 
2、使用动态库
编译执行文件
gcc test.c -I./  -L./ -ltest 
通过ldd命令查看可执行问价噢爱你依赖的动态库
$# ldd a.out 
linux-vdso.so.1 (0x00007ffc2eb32000)
libtest.so (0x00007ff241178000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff240f71000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff241184000) 
执行
nm libtest.so | grep add 
- 当系统加载可执行代码时候,能够知道其所依赖的库的名字但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。
 - 对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 D_ RPATH段一 环境变量LD_LIBRARY_PATH – /etc/ld.so.cache文件列表 -/lib/,/usr/lib目录找到库文件后将其载入内存
 
让系统找到动态库
-  
拷贝目录,拷贝自己制作的共享库到/lib或者/usr/lib(不能是/lib64目录)
 -  
临时设置LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径 -  
永久设置1,把
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径,设置到~/.bashrc或者/etc/profile文件中 
# 编辑.bashrc最后一行添加如下内容:
deng@itcast:-/share/3rd/2share test$ vim ~/.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cpp_test/library/test
# 或者执行文件夹
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cpp_test/library/
# 使环境变量生效
source ~/.bashrc
 
- 永久设置2,将其添加到
/etc/ld.so.conf文件中
编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
运行sudo ldconfig -v,该命令会重建 /etc/ld.so.conf 
sudo vim /etc/ld.so.conf
# 文件最后添加动态库路径(绝对路径)
/usr/local/cpp_test/library/test
# 使生效
sudo ldconfig -v 
- 符号链接:一定要使用绝对路径
 
sudo ln -s /usr/local/cpp_demo/library/libtest.so /lib/libtest.so
相关文章:
linux入门到精通-第五章-动态库和静态库
目录 参考概述1、静态链接2 、动态链接3 、静态、动态编译对比 静态库和动态库简介传统编译 静态库制作和使用1、创建静态库的过程2、使用静态库 动态库制作和使用1、创建动态库的过程1)、生成目标文件,此时要加编译选项:-fPIC (f…...
markdown 如何更改字体以及颜色等功能
markdown 是IT人士写文档的常用方式,但是markdown默认又不支持颜色字体等特殊功能,所以呢想实现字体颜色高亮等特殊功能,实现的方法呢就是使用HTML,所以将部分文字改成HTML代码就行 颜色 <font color#0099ff>color #0099f…...
一次cs上线服务器的练习
环境:利用vm搭建的环境 仅主机为65段 测试是否能与win10ping通 配置转发 配置好iis Kali访问测试 现在就用burp抓取winser的包 开启代理 使用默认的8080抓取成功 上线...
STM32-高级定时器
以STM32F407为例。 高级定时器 高级定时器比通用定时器增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能都是针对工业电机控制方面。 功能框图 16位向上、向下、向上/向下自动重装载计数器。 16位可编程预分频器,…...
三季度业绩狂飙后,贝泰妮将开启集团化运营的“中场战事”?
双十一前夕,贝泰妮交出了一份亮眼的答卷。 得益于销售端和研发端的发展动能强劲,第三季度贝泰妮营收10.64亿元,同比增长25.77%;扣非净利润1.34亿元,同比增长39.88%。 如此亮眼的业绩,自然引得资本市场侧目…...
快速了解:什么是优化问题
1. 定义 数学优化问题是:在给定约束条件下,找到一个目标函数的最优解(最大值或最小值)。 2. 快速get理解 初学者对优化技术陌生的话,可以把 “求解优化问题” 理解为 “解一个不等式方程组”,解方程的。…...
Unity在Project右键点击物体之后获取到点击物体的名称
Unity在Project右键点击物体之后获取到点击物体的名称 描述: 在Unity的Project右键点击物体之后选择对应的菜单选项点击之后打印出物体的名称 注意事项 如果获取到文件或者预制体需要传递objcet类型,然后使用 GameObject.Instantiate((GameObject)se…...
【带头学C++】----- 三、指针章 ---- 3.7 数组指针
3.7 数组指针 1.数组指针的概述 数组指针是一个指向数组的指针变量,是用来保存数组元素的地址。在C/C中,数组名代表了数组的首地址,可以被解释为一个指向数组第一个元素的指针。因此,一个指向数组的指针可以通过数组名来获…...
Ubuntu20.04安装CUDA、cuDNN、tensorflow2可行流程(症状:tensorflow2在RTX3090上运行卡住)
最近发现我之前在2080ti上运行好好的代码,结果在3090上运行会卡住很久,而且模型预测结果完全乱掉,于是被迫研究了一天怎么在Ubuntu20.04安装CUDA、cuDNN、tensorflow2。 1.安装CUDA(包括CUDA驱动和CUDA toolkit,注意此…...
untiy打开关闭浏览器
最简单的打开方法,只能打开不能关闭,自动打开默认浏览器 Application.OpenURL("https://www.bilibili.com/");打开关闭谷歌浏览器 using System.Diagnostics;private static Process web;if (web null)//打开 {web Process.Start("Chr…...
独立站优缺点解析,如何用黑科技进行缺点优化
随着跨境电商第三方平台平台红利越来越少,经营风险的不断增加,大部分人知道前年发生的亚马逊封店潮,涉及约1000家企业,5万多个账号,预估损失超过千亿元。 正因如此,更多的国内品牌和卖家不再仅依赖于第三方…...
道本科技||紧跟数字化转型趋势,企业如何提高合同管理能效?
随着数字化转型的快速发展,合同管理对于企业的运营效率和风险控制起着至关重要的作用。那么,如何紧跟数字化转型趋势,利用现代技术和工具提高合同管理的能效,以实现企业更高效、更安全的合同管理就成了企业管理中的核心问题。 在…...
框架安全-CVE 复现Apache ShiroApache Solr漏洞复现
文章目录 服务攻防-框架安全&CVE 复现&Apache Shiro&Apache Solr漏洞复现中间件列表常见开发框架Apache Shiro-组件框架安全暴露的安全问题漏洞复现Apache Shiro认证绕过漏洞(CVE-2020-1957)CVE-2020-11989验证绕过漏洞CVE_2016_4437 Shiro-…...
【OpenCV实现图像梯度,Canny边缘检测】
文章目录 概要图像梯度Canny边缘检测小结 概要 OpenCV中,可以使用各种函数实现图像梯度和Canny边缘检测,这些操作对于图像处理和分析非常重要。 图像梯度通常用于寻找图像中的边缘和轮廓。在OpenCV中,可以使用cv2.Sobel()函数计算图像的梯度…...
Spring Boot 解决跨域问题的 5种方案
跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。 一、跨域三种情况 在请求时,如果出现了以下情况中的任意一种,那么它就是跨域请求: 协议不同,如 http 和 https…...
linux 3.13版本nvme驱动阅读记录一
内核版本较低的nvme驱动代码不多,而且使用的是单队列的架构,阅读起来会轻松一点。 这个版本涉及到的nvme驱动源码文件一共就4个,两个nvme.h文件,分别在include/linux ,include/uapi/linux目录下,nvme-core.c是主要源码…...
掌握RESTful API:规范与设计详解
前言 RAML (RESTful API Modeling Language) 和 OAS (OpenAPI Specification) 都是用于描述和定义 RESTful API 的规范。它们分别提供了不同的功能和优势。 RAML(RESTful API Modeling Language): RAML简介 RAML(RESTful API M…...
「更新」Topaz Video AI v4.0.3中文版
Topaz Video AI是一款功能强大的视频处理软件,它利用人工智能技术对视频进行智能分析和优化,旨在为用户提供高效、智能的视频编辑和增强功能。 首先,Topaz Video AI具备强大的视频修复功能。它可以自动识别并修复视频中的各种问题࿰…...
OpenAI最新官方GPT最佳实践指南,一文讲清ChatGPT的Prompt玩法
原文:Sina Visitor System OpenAI的官网发表万字GPT最佳实践指南,讲清Prompt提示词的原则和策略,这里是总结和全文翻译 原创图像,AI辅助生成 OpenAI的官网上刚刚发表一篇万字的GPT最佳实践指南,这份指南把写好Promp…...
树结构及其算法-用链表来实现二叉树
目录 树结构及其算法-用链表来实现二叉树 C代码 树结构及其算法-用链表来实现二叉树 以链表实现二叉树就是使用链表来存储二叉树,也就是运用动态分配内存和指针的方式来建立二叉树。 使用链表来表示二叉树的好处是节点的增加与删除操作相当容易,缺点…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
