linux动态链接库
前言
静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费
静态链接库对程序的更新、部署、发布带来麻烦。如果静态库更新了,使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)
动态库在程序编译时并不会被链接到目标代码中,而是在执行文件中记录对动态库的引用,在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署和发布带来的麻烦,用户只需要更新动态库即可,增量更新。
Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件。
特点
- 动态库把对一些库函数的链接载入推迟到程序运行的时期
- 可以实现进程之间的资源共享。(因此动态库也称为共享库)
- 将一些程序升级变得简单。
- 甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)
生成动态链接库
- 编写源文件
- 将一个或几个源文件编译链接,生成共享库。
- 通过 -L<path> -lxxx 的gcc选项链接生成的libxxx.so。
- 把 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(, ), subtract(, )); return ;
}
链接
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
这涉及到程序如何定位共享库文件
- 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)
- 对于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: all all: build target build: libmymath.so
libmymath.so: add.o subtract.o
gcc -o $@ -shared $^
add.o: add.c
gcc -c -fPIC $<
subtract.o: subtract.c
gcc -c -fPIC $< target: a.out
a.out: main.c
gcc main.c -L. -lmymath .PHONY: clean
clean:
rm *.o a.out libmymath.so
linux动态链接库的更多相关文章
- Linux动态链接库的创建与使用
Linux动态链接库的创建与使用1. 介绍 使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数 ...
- linux 动态链接库查找方法;查找动态链接库位置; LIBRARY_PATH 和 LD_LIBRARY_PATH 的区别;LD_LIBRARY_PATH and LD_RUN_PATH的区别;
今天配置之前项目的时候,发现有些动态链接库变了,想看看现在应用在使用哪些动态链接库的时候,进一步查了点资料: 下面针对linux动态链接库查找方法和动态链接库位置配置的过程进行记录: LIBRARY_ ...
- Linux 动态链接库
如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...
- Linux 动态链接库学习笔记
参考资料: http://www.linuxidc.com/Linux/2012-01/50739.htm http://www.yolinux.com/TUTORIALS/LibraryArchiv ...
- linux动态链接库---一篇讲尽
一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...
- Linux动态链接库的生成和使用
目录 1. 编写C程序 2. 编译动态链接库 3. 使用共享库 4. 执行程序 5. 参考资料 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是ca ...
- Linux 动态链接库 - dll劫持
如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...
- Linux 动态链接库(.so)的使用
1. 背景 库:就是已经编写好的,后续可以直接使用的代码. c++静态库:会合入到最终生成的程序,使得结果文件比较大.优点是不再有任何依赖. c++动态库:动态库,一个文件可以多个代码同时使用内存中只 ...
- Linux动态链接库的使用
1.前言 在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找.排序.为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库.通过动态链接库可以实现多个 ...
随机推荐
- c# 的传递参数值传递与传递引用的区别,ref与out区别
值传递 C#默认都是值传递的,就是复制变量的一个副本传递给方法,所以在退出方法后,对变量的修改无效. 但是要注意,当传递是引用类型时,因为引用类型是一个引用的地址,所以修改引用地址指向的对象时,一样会 ...
- 安装python File "/usr/bin/pip", line 11, in <module> sys.exit(main()) File "/usr/lib/python3.4/site-packages/pip/__init__.py", line 215, in main locale.setlocale(locale.LC_ALL, '') File "/u
$ uname -a Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 GNU ...
- CDN缓存策略
以下内容就是FAQ,自己也学习一下... 1.CDN加速原理通过动态域名解析,网友的请求被分配到离自己最快的服务器.CDN服务器直接返回缓存文件或通过专线代理原站的内容.网络加速+内容缓存,有效提供访 ...
- easyui学习笔记9—手风琴格子的增,删和选择
这一篇中我们将看看如何给手风琴动态的增加,删除格子,怎样选择某一个格子的. 1.先看看引用的资源 <link rel="stylesheet" href="jque ...
- Core Animation 与 GPU
https://en.wikipedia.org/wiki/Core_Animation#cite_note-apptech-1 Core Animation provides a way for d ...
- Yii的事件和行为的区别和应用
关于 Yii 的事件和行为的描述,可参考 http://www.yiiframework.com/doc/api/1.1/CComponent 事件 事件模型就是设计模式中的“观察者模式”:当对象的状 ...
- Qgis 里的Python脚本介绍
QGIS 入门演示之<用 QGIS 画矢量交通路线图> 脚本编程之准备知识<Python 教程> QGIS API QGIS插件库 运行QGIS脚本,对于桌面应用来讲有4种方式 ...
- 截屏快捷键(windows)自带截屏,不需要安装任何插件
方案一:电脑自带截屏,不需要QQ Shift+win+s即可截图(推荐使用) 方案二:搜狗输入法下载自带:Ctrl+Shift+x
- 手机站全局的html+css加载等待效果
本文只提供思路,CSS神马的自己定制吧,JS是可以优化的,比如,输出图片的JS也可以放到showdiv()里面,我没有做优化,只是实现,别笑话我,我比较懒... 基本思路:由于Html的解析是从上到下 ...
- Code First 二 DataAnnotation 数据注解
Code-First中配置域类 我们在前一节学习了默认的代码优先约定.Code-First使用默认约定从您的域类构建概念模型.Code-First利用称为约定而不是配置的编程模式.这意味着您可以通过配 ...