当前位置: 首页 > news >正文

Linux动态库制作和使用

文章目录

  • 动态库制作和使用
    • 动态库制作
    • 动态库测试
    • 动态库加载失败问题解决
      • 方法1. 将动态库拷贝到系统库目录下
      • 方法2. 临时设置LD_LIBRARY_PATH环境变量
      • 方法3. 永久设置 将环境变量添加到配置文件中
      • 方法4. 修改配置文件/etc/ld.so.conf
      • 方法5. 创建软链接

动态库制作和使用

动态库(共享库)在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。

动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。

按照习惯,一般以“.so”做为文件后缀名。共享库的命名一般分为三个部分:

  • 前缀:lib
  • 库名称:自己定义即可
  • 后缀:.so

所以最终的动态库的名字应该为:libxxx.so

动态库制作

步骤一:生成目标文件,此时要加编译选项:-fPIC(fpic)

wuyou@itcast:~/test/5share_lib$ gcc -fPIC -c add.c wuyou@itcast:~/test/5share_lib$ gcc -fPIC -c sub.c wuyou@itcast:~/test/5share_lib$ gcc -fPIC -c mul.c wuyou@itcast:~/test/5share_lib$ gcc -fPIC -c div.c 

参数:-fPIC 创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享。

步骤二:生成共享库,此时要加链接器选项: -shared(指定生成动态链接库)

wuyou@itcast:~/test/5share_lib$ gcc -shared add.o sub.o mul.o div.o -o libtest.so

步骤三: 通过nm命令查看对应的函数是否存在

#00000000000006b0 add 表示函数存在, 00000000000006b0: 表示地址偏移量 T:表示代码段wuyou@itcast:~/test/5share_lib$ nm libtest.so | grep add 
00000000000006b0 T add  
wuyou@itcast:~/test/5share_lib$ nm libtest.so | grep sub 
00000000000006c4 T sub

ldd查看可执行文件的依赖的动态库

wuyou@itcast:~/share/3rd/2share_test$ ldd a.outlinux-vdso.so.1 (0x00007ffc48189000)libtest.so => not foundlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe17a7f3000)/lib64/ld-linux-x86-64.so.2 (0x00007fe17ade6000)
wuyou@itcast:~/share/3rd/2share_test$ 

动态库测试

引用动态库编译成可执行文件(跟静态库方式一样)

wuyou@itcast:~/test/6share_test$ gcc test.c -L. -I. -ltest (-I. 大写i -ltest 小写L)

然后运行:./a.out,发现竟然报错了!!!

wuyou@itcast:~/share/3rd/2share_test$ ls
add.h  div.h  libtest.so  main.c  mul.h  sub.h
wuyou@itcast:~/share/3rd/2share_test$ gcc main.c -I./ -L./ -ltest
wuyou@itcast:~/share/3rd/2share_test$ ./a.out 
./a.out: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
wuyou@itcast:~/share/3rd/2share_test$ 
  • 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。
  • 对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段 — 环境变量LD_LIBRARY_PATH — /etc/ld.so.cache文件列表 — /lib/, /usr/lib目录找到库文件后将其载入内存。

动态库加载失败问题解决

方法1. 将动态库拷贝到系统库目录下

wuyou@itcast:~/share/3rd/2share_test$ ls
add.h  a.out  div.h  libtest.so  main.c  mul.h  sub.h
wuyou@itcast:~/share/3rd/2share_test$ sudo cp libtest.so /usr/lib/
[sudo] wuyou 的密码: 
wuyou@itcast:~/share/3rd/2share_test$ ls -l /usr/lib/libtest.so 
-rwxr-xr-x 1 root root 7608 116 09:40 /usr/lib/libtest.so
wuyou@itcast:~/share/3rd/2share_test$ ./a.out 
x + y = 18
x - y = 12
x * y = 45
x / y = 5
wuyou@itcast:~/share/3rd/2share_test$ 

方法2. 临时设置LD_LIBRARY_PATH环境变量

wuyou@itcast:~/share/3rd/2share_test$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wuyou/share/3rd/2share_test
wuyou@itcast:~/share/3rd/2share_test$ ./a.out  
x + y = 18
x - y = 12
x * y = 45
x / y = 5
wuyou@itcast:~/share/3rd/2share_test$ 

方法3. 永久设置 将环境变量添加到配置文件中

wuyou@itcast:~/share/3rd/2share_test$ vim ~/.bashrc 
#最后一行添加如下行
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wuyou/share/3rd/2share_testwuyou@itcast:~/share/3rd/2share_test$ ./a.out 
./a.out: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory#使配置文件生效
wuyou@itcast:~/share/3rd/2share_test$ source  ~/.bashrc  
wuyou@itcast:~/share/3rd/2share_test$ ./a.out  
x + y = 18
x - y = 12
x * y = 45
x / y = 5
wuyou@itcast:~/share/3rd/2share_test$ 

方法4. 修改配置文件/etc/ld.so.conf

wuyou@itcast:~/share/3rd/2share_test$ sudo vim /etc/ld.so.conf#最后一行添加库的路径
/home/wuyou/share/3rd/2share_test#使生效
wuyou@itcast:~/share/3rd/2share_test$ sudo ldconfig -vwuyou@itcast:~/share/3rd/2share_test$ ./a.out  
x + y = 18
x - y = 12
x * y = 45
x / y = 5
wuyou@itcast:~/share/3rd/2share_test$ 

方法5. 创建软链接

#创建软链接
wuyou@itcast:~/share/3rd/2share_test$ sudo ln -s /home/wuyou/share/3rd/2share_test/libtest.so  /usr/lib/libtest.so
wuyou@itcast:~/share/3rd/2share_test$ ./a.out  
x + y = 18
x - y = 12
x * y = 45
x / y = 5
wuyou@itcast:~/share/3rd/2share_test$ 
http://www.dtcms.com/a/343013.html

相关文章:

  • Manus AI 与多语言手写识别:技术、应用与未来
  • Nginx + Vue/React 前端 + API:防止路径混淆漏洞与跨域问题实战分享
  • [Mysql数据库] Mysql安全知识
  • Oracle ADG 切换方式详解:Switchover 与 Failover 操作指南
  • 〖领码方案〗前端 PageData 完整解决方案 第四版
  • 深度解析Structured Outputs:让AI输出严格遵循JSON Schema的结构化响应
  • 【日常学习】2025-8-21 了解些测试名词
  • 【GPT入门】第52课 openwebui安装与使用
  • Zynq中级开发七项必修课-第三课:S_AXI_GP0 主动访问 PS 地址空间
  • 通信算法之317:基于Xilinx FPGA平台的符号同步算法(接收序列与本地序列互相关-不共轭乘)
  • ODDR实现多bit单边沿采样数据转为多bit双沿采样数据
  • 前端-Vue笔记(核心语法)
  • linux内核 - 内存分配机制介绍
  • MySQL 8.4.6 LTS 安装教程 windows
  • 如何在mac玩windows游戏?3个工具推荐,不用换电脑!
  • MiniGPT-4
  • 在Excel和WPS表格中合并多个单元格这样最快
  • 第14章 结构和其他数据形式
  • 数据分类分级的关键难点以及应对之道
  • Go1.25的源码分析-src/runtime/runtime1.go(GMP)g
  • U盘安装 CentOS Stream 10 实战复盘:三大常见问题与解决方法
  • 通义千问VL-Plus:当AI“看懂”屏幕,软件测试的OCR时代正式终结!
  • Java 项目中 MySQL 数据向 Redis 迁移的技术实践与深度剖析
  • JVM 性能监控工具全解析:从命令行到可视化全方位指南
  • 图像形态学:膨胀、腐蚀和边缘检测与绘制
  • Java后端面试场景题大全:2025年高频考点深度解析
  • 大模型部署
  • 造成云手机闪退的原因有哪些?
  • 使用VBA宏批量修改Word中表格题注格式
  • HYPE分布式水文模型建模方法与案例分析实践技术应用