静态库与动态库文件的制作与使用
静态库与动态库
什么是库文件?
-
提供变量,函数/类的封装的代码仓库
-
不能单独运行 而一般的程序文件可以单独运行
-
分为静态库和动态库
-
好处: 代码保密 方便部署和分发
动态库与静态库的区别
静态库在程序链接阶段被复制到程序中, 动态库在程序运行时由系统定位动态库文件并加载到内存中使用
库类型 | 优点 | 缺点 |
---|---|---|
静态 | 打包到应用程序中加载速度快 | 消耗系统资源,浪费内存 |
发布程序无需提供静态库,移植方便 | 更新、部署、发布麻烦 | |
动态 | 可以实现进程间资源共享(共享库) | |
更新、部署、发布简单 | 加载速度比静态库慢 运行时需要查找库再加入 | |
可以控制何时加载动态库 | 发布程序时需要提供依赖的动态库 |
命名规则
静态库
Linux: libxxx.a 只有xxx是自定义
Windows:libxxx.lib xxx自定义
动态库
Linux:libxxx.so
Windows:libxxx.dll
库的制作与使用
静态
r 将文件插入备存文件(备存文件?)
c 建立备存文件索引
s 索引
gcc a.c b.c -o a.o b.o
ar rcs libxxx.a a.o b.o
当前文件
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# tree
.
├── add.c
├── div.c
├── head.h
├── libcalc.a
├── main.c
├── mult.c
└── sub.c
编译成目标文件
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# gcc -c add.c div.c mult.c sub.c
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
创建静态库
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# ar rcs libcalc.a sub.o div.o mult.o add.o
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.a
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
使用静态库
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# tree
.
├── include
│ └── head.h
├── lib
│ └── libcalc.a
├── main.c
└── src
├── add.c
├── div.c
├── mult.c
└── sub.c
编译main程序头文件
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# gcc main.c -o app
main.c:2:10: fatal error: head.h: No such file or directory
2 | #include "head.h"
| ^~~~~~~~
compilation terminated.
提供了头文件 但找不到定义的内部内容
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# gcc main.c -o app -I ./include/
/usr/bin/ld: /tmp/ccmLoZI5.o: in function `main':
main.c:(.text+0x3e): undefined reference to `add'
/usr/bin/ld: main.c:(.text+0x60): undefined reference to `subtract'
/usr/bin/ld: main.c:(.text+0x82): undefined reference to `multiply'
/usr/bin/ld: main.c:(.text+0xa4): undefined reference to `divide'
collect2: error: ld returned 1 exit status
提供静态库
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# gcc main.c -o app -I ./include/ -l calc -L ./lib/
执行程序
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession05/library# ./app
a = 20, b = 12
a+b= 32
a-b= 8
a*b= 240
a/b= 1.666667
动态
ldd list dynamic dependencies 检查依赖
定位共享库文件
知道库的名字不够,它会先后搜索elf文件的 DT_RPATH段 ——> 环境变量
LD_LIBRARY_PATH ——> /etc/ld.so.cache文件列表 ——> /lib/,/usr/lib
目录找到库文件后将其载入内存
- 使用LD_LIBRARTY_PATH
- 使用/lib/, /usr/lib/
动态库制作
├── calc
│ ├── add.c
│ ├── div.c
│ ├── head.h
│ ├── main.c
│ ├── mult.c
│ └── sub.c
└── library
├── include
│ └── head.h
├── lib
│ └── libcalc.so
├── main
├── main.c
└── src
├── add.c
├── div.c
├── mult.c
└── sub.c
生成位置无关代码
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# gcc -c -fpic add.c div.c mult.c sub.c
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
生成共享动态库
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# gcc -shared *.o -o libcalc.so
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/calc# tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.so
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
使用动态库
├── include
│ └── head.h
├── lib
│ └── libcalc.so
├── main
├── main.c
└── src
├── add.c
├── div.c
├── mult.c
# gcc main.c -o main -I ./include/ -L ./lib/ -l calc
# ldd main 查看依赖关系
提示无法找到共享库时
使用以下三种方法 定位动态库文件 因为动态库是在最后加入内存
环境变量LD_LIBRARY_PATH
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH : /root/Linux/lession06/library/lib 暂时的环境变量 重启终端后删除
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/library# ldd
ldd: missing file arguments
Try `ldd --help' for more information.
root@iZwz953bcwdl9hfnde2odsZ:~/Linux/lession06/library# ldd main
linux-vdso.so.1 (0x00007ffc1cd4d000)
libcalc.so => /root/Linux/lession06/library/lib/libcalc.so (0x00007f7a5f3bf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7a5f1c6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7a5f3cb000)
vim .bashrc 用户级别永久环境变量
最后插入export LD_LIBRARY_PATH = $LD_LIBRARY_PATH : /root/Linux/lession06/library/lib
. .bashrc或者source .bashrc
vim /etc/profile 系统级别环境变量
下同上
配置/etc/ld.so.cache文件列表
二进制文件无法直接修改 因此间接
# vim /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
/root/Linux/lession06/library/lib 插入的内容
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)