前言

静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费

静态链接库对程序的更新、部署、发布带来麻烦。如果静态库更新了,使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)

动态库在程序编译时并不会被链接到目标代码中,而是在执行文件中记录对动态库的引用,在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署和发布带来的麻烦,用户只需要更新动态库即可,增量更新。

Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件。

特点

  • 动态库把对一些库函数的链接载入推迟到程序运行的时期
  • 可以实现进程之间的资源共享。(因此动态库也称为共享库)
  • 将一些程序升级变得简单。
  • 甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

生成动态链接库

  1. 编写源文件
  2. 将一个或几个源文件编译链接,生成共享库。
  3. 通过 -L<path> -lxxx 的gcc选项链接生成的libxxx.so。
  4. 把 libxxx.so 放入链接库的标准路径,或指定 LD_LIBRARY_PATH,才能运行链接了libxxx.so的程序。

例子

源文件

add.c

int add(int a, int b)
{return a + b;
}

subtract.c

int subtract(int a, int b)
{return a - b;
}

编译

gcc -fPIC -c add.c
gcc -fPIC -c subtract.c

其中,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性

链接

gcc -shared -o libmymath.so subtract.o add.o

-shared是链接选项,告诉gcc生成动态库而不是可执行文件

这两步可以合并成一个命令:

gcc -o libmymath.so -fPIC -shared subtract.c add.c

编写头文件

#ifndef _MYMATH_H_
#define _MYMATH_H_int add(int, int);
int subtract(int, int);#endif

使用链接库

main.c

#include <stdio.h>
#include "mymath.h"int main()
{printf("%d, %d\n", add(2, 3), subtract(9, 8));return 0;
}

链接

gcc main.c -L. -lmymath

如果同一目录下同时存在同名的动态库和静态库,比如 libmymath.so 和 libmymath.a 都在当前路径下,则gcc会优先链接动态库。

运行

当执行 ./a.out,发现程序报错

./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

这涉及到程序如何定位共享库文件

  1. 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)
  2. 对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段 -- 环境变量LD_LIBRARY_PATH -- /etc/ld.so.cache文件列表 -- /lib/,/usr/lib 目录找到库文件后将其载入内存。

/etc/ld.so.cache 是 ldconfig 程序读取 /etc/ld.so.conf 文件生成的

所以,我们想让程序找到自己写的动态链接库,有如下方法:

  • 指定 LD_LIBRARY_PATH 环境变量为 libmymath.so 文件所在的目录
  • 编辑/etc/ld.so.conf文件,加入库文件所在目录的路径; 同时,运行ldconfig ,该命令会重建/etc/ld.so.cache文件
  • 把 libmymath.so 拷贝到/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作

我们可以执行:

LD_LIBRARY_PATH=. ./a.out

Makefile

.PHONY: allall: build targetbuild: libmymath.so
libmymath.so: add.o subtract.ogcc -o $@ -shared $^
add.o: add.cgcc -c -fPIC $<
subtract.o: subtract.cgcc -c -fPIC $<target: a.out
a.out: main.cgcc main.c -L. -lmymath.PHONY: clean
clean:rm *.o a.out libmymath.so

转载于:https://www.cnblogs.com/zuofaqi/p/10440754.html

linux动态链接库相关推荐

  1. LINUX动态链接库高级应用

    在< LINUX下动态链接库的创建与应用> 一文中,我介绍了LINUX动态链接库的基本知识.其要点是:用户根据实际情况需要,利用dlopen,dlsym,dlclose等动态链接库操作函 ...

  2. Linux动态链接库的使用

    Linux动态链接库的使用 1.前言 在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找.排序.为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库 ...

  3. 转]Window, Linux动态链接库的分析对比

    转]Window, Linux动态链接库的分析对比 摘 要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高 ...

  4. linux 动态链接库的创建和使用--动态连接

    linux 动态链接库的创建和使用--动态连接 分类: C 编程 2012-03-25 17:01 568人阅读 评论(0) 收藏 举报 linuxreferencefunctiondatec /* ...

  5. linux .so文件u xxx,Linux动态链接库.so文件创建与使用.pdf

    Linux动态链接库.so文件创建与使用 匡 参 炕 老 眨 询 集 提 度 襟 镐 爹 佑 萎 位 扣 纶 宋 浆 孕 昨 爆 做 阅 校 认 分 朽 双 丘 墓 洼 傻 算 露 兢 念 咏 刷 狰 ...

  6. linux动态链接库全局变量共享问题DLL共享数据段

    Linux写时拷贝技术(copy-on-write) 进程间是相互独立的,其实完全可以看成A.B两个进程各自有一份单独的liba.so和libb.so,相应的动态库的代码段和数据段都是各个进程各自有一 ...

  7. Linux动态链接库编程入门

    Linux动态链接库编程入门 转:http://blog.csdn.net/yang_rong_yong/article/details/3090212 动态链接库是一种通用的软件组件技术,是多种操作 ...

  8. linux生成动态链接库返回字符串,Linux动态链接库的生成和使用

    目录 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是cal_sum. #include "myfunc.h" void say ...

  9. LINUX动态链接库的创建与使用

    大家都知道,在 WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一 ...

  10. 如何查看linux动态链接库文件的版本等其他信息

    ldd <可执行文件名> 查看可执行文件链接了哪些 系统动态链接库nm <可执行文件名> 查看可执行文件里面有哪些符号strip <可执行文件名> 去除符号表可以给 ...

最新文章

  1. 【每日一算法】罗马数字转整数
  2. webAPP优化方案总结
  3. 声学、音乐计算常用工具总结(soundfile、librosa、pydub、madmom、spleeter)
  4. 白鹭引擎助力《迷你世界》研发团队开发3D小游戏版
  5. 【STM32】FreeRTOS下载和介绍
  6. java 模板实现原理,Java Web 模板代码生成器的设计与实现详解
  7. Jupyter Notebook 常用的快捷键
  8. oracle错误: ORA-00600: 内部错误代码, 参数: [kkqcscpopn_Int: 0], [], [], [], [], [], [], [], [], [], [], []...
  9. 一文教你如何使用 MongoDB 和 HATEOAS 创建 REST Web 服务
  10. java怎么使用wcf_如何使用WCF服务
  11. 博罗县房产管理局应用级本地容灾备份系统采购项目
  12. JSP的自定义标签(五)之Tag File
  13. ImageView显示控制
  14. 使用stm32驱动RC522读取IC卡
  15. 瑞幸的野望,小鹿茶的突袭
  16. Pygame制作音乐播放器
  17. AlertManager实现企业微信报警(十三)
  18. 海思平台项目经验总结
  19. 分布式数据库——分片透明、复制透明、位置透明、逻辑透明
  20. git commit报错subject may not be empty

热门文章

  1. 使用ASP.NET AJAX异步调用Web Service和页面中的类方法(2):处理异步调用中的异常...
  2. 背包类树形DP 选课题解
  3. Docker最全教程——数据库容器化之持久保存数据(十一)
  4. winform npoi excel 样式设置
  5. (Sql Server)SQL FOR XML PATH
  6. 项目管理(五)- 风险检测表
  7. ASP.NET使用AJAX应注意IIS有没有.ashx扩展
  8. [转]31个让你变聪明的方法
  9. 千山独行-一个人的创业路(连载五)
  10. 为什么有必要对网站开启https?