linux 动态静态库
库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。
1 静态库和动态库的区别
1.1. 静态函数库
(1)静态函数库的名字一般是lib[name].a
(2)利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,它的优点是编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。这给它带来的缺点为如果静态函数库改变了,那么你的程序必须重新编译。
1.2. 动态函数库
(1)动态函数库的名字一般是lib[name].so
(2)相对于静态函数库,动态函数库所产生的可执行文件比较小,动态函数库在编译的时候 并没有被编译进目标代码中,程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的 程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。
(3)linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。
2 编写及使用静态库
静态库的制作所要用到的命令:gcc和ar 命令。
2.1 编写静态库的步骤为:
2.1.1 创建编辑源代码文件: pr1.c 和 pr2.c
pr1.c:
void print1()
{
printf("This is the first lib src!\n");
}
pr2.c
void print2()
{
printf("This is the second src lib!\n");
}
2.1.2 编译.c 文件
gcc -O -c pr1.c pr2.c
2.1.3 链接静态库
在编译程序中正确找到库文件,静态库必须按照 lib[name].a 的规则命名,如下例中[name]=pr.
(1)ar -rsv libpr.a pr1.o pr2.o
a - pr1.o
a - pr2.o
(2) ar t ibpr.a
pr1.o
pr2.o
2.1.4 调用库函数代码 main.c
main.c
int main()
{
print1();
print2();
return 0;
}
2.1.5 编译链接选项
-L 及-l 参数放在后面.其中-L 加载库文件路径,-l 指明库文件名字.
gcc -o main main.c -L./ -lpr
2.1.6 执行目标程序
3 编写动态库
3.1 设计库代码
pr1.c :
int p = 2;
void print()
{
printf("This is the first dll src!\n");
}
3. 2 生成动态库
gcc -O -fpic -shared -o dl.so pr1.c
4 动态库的使用
4.1 动态库的隐式调用
在编译调用库函数代码时指明动态库的位置及名字
main.c :
int main()
{
print();
return 0;
}
gcc -o tdl main.c ./dl.so
当动态库的位置或者名字发生改变时, 程序将无法正常运行; 而动态库取代静态库的好处之一则是通过更新动态库而随时升级库的内容.
4.2 动态库的显式调用
显式调用动态库需要四个函数的支持,
(1)函数 dlopen 打开动态库,
(2)函数 dlsym 获取动态库中对象基址,
(3)函数 dlerror 获取显式动态库操作中的错误信息,
(4)函数 doclose 关闭动态库.
main.c :
#include <dlfcn.h>
int main()
{
void *pHandle;
void (*pFunc)(); // 指向函数的指针
int *p;
pHandle = dlopen("./d1.so", RTLD_NOW); // 打开动态库
if(!pHandle)
{
printf("Can't find d1.so \n");
exit(1);
}
pFunc = (void (*)())dlsym(pHandle, "print"); // 获取库函数 print 的地址
if(pFunc)
{
pFunc();
}
else
{
printf("Can't find function print\n");
}
p = (int *)dlsym(pHandle, "p"); // 获取库变量 p 的地址
if(p)
{
printf("p = %d\n", *p);
}
else
{
printf("Can't find int p\n");
}
dlclose(pHandle); // 关闭动态库
return 0;
}
gcc -o tds main.c –ld1 –L.
此 时还不能立即./tds,因为在动态函数库使用时,会查找/usr/lib、/lib目录下的动态函数库,而此时我们生成的库不在里边。
解决方法有:
(1)最直接最简单的方法就是把生成的动态链接库放到/usr/lib或/lib中去。
(2) export LD_LIBRARY_PATH=$(pwd)
(3)另外还可以在/etc/ld.so.conf文件里加入我们生成的库的目录,然后/sbin/ldconfig。 /etc/ld.so.conf是非常重要的一个目录,里面存放的是链接器和加载器搜索共享库时要检查的目录,默认是从/usr/lib /lib中读取的,所以想要顺利运行,我们也可以把我们库的目录加入到这个文件中并执行/sbin/ldconfig 。另外还有个文件需要了解/etc/ld.so.cache,里面保存了常用的动态函数库,且会先把他们加载到内存中,因为内存的访问速度远远大于硬盘的 访问速度,这样可以提高软件加载动态函数库的速度了。
5 库依赖的查看
使用ldd命令来查看执行文件依赖于哪些库。
该命令用于判断某个可执行的 binary 档案含有什么动态函式库。
ldd [-vdr] [filename]
参数说明:
--version 打印ldd的版本号
-v --verbose 打印所有信息,例如包括符号的版本信息
-d --data-relocs 执行符号重部署,并报告缺少的目标对象(只对ELF格式适用)
-r --function-relocs 对目标对象和函数执行重新部署,并报告缺少的目标对象和函数(只对ELF格式适用)
--help 用法信息。
如果命令行中给定的库名字包含'/',这个程序的libc5版本将使用它作为库名字;否则它将在标准位置搜索库。运行一个当前目录下的共享库,加前缀"./"。
linux 动态静态库的更多相关文章
- Linux上静态库和动态库的编译和使用
linux上静态库和动态库的编译和使用(附外部符号错误浅谈) 这就是静态库和动态库的显著区别,静态库是编译期间由链接器通过include目录找到并链接到到可执行文件中,而动态库则是运行期间动态调用,只 ...
- linux下静态库的制作
在我们编写软件的过程当中,少不了需要使用别人的库函数.因为大家知道,软件是一个协作的工程.作为个人来讲,你不可能一个人完成所有的工作.另外,网络上一些优秀的开源库已经被业内广泛接受,我们也没有必要把 ...
- Linux下静态库生成和使用
Linux下静态库生成和使用 一.静态库概念 1.库是预编译的目标文件(object files)的集合,它们可以被链接进程序.静态库以后缀为”.a”的特殊的存档(archive file)存储. ...
- linux上静态库链接的有关问题
求大神,linux下静态库链接的问题有两个文件和一个库,a.c, b.c,libh.a,其中b.c里面会有调用libh.a的函数func1,现在将a.c, b.c,libh.a编译链接生成可执行文件, ...
- linux c: 静态库和动态库的生成和使用
场景: main函数需要两个接口,一个求和函数,一个打印函数. int sum(int i, int j); 求两个int数字的和. void show(int i, char* name); 打印i ...
- [转帖]Linux 的静态库与动态库
Linux下的静态库与动态库 2017年02月18日 09:17:13 LLZK_ 阅读数:10257 标签: linux动态库静态库区别使用 更多 个人分类: Linux学习笔记 所属专栏: Lin ...
- linux上静态库和动态库的编译和使用(附外部符号错误浅谈)
主要参考博客gcc创建和使用静态库和动态库 对于熟悉windows的同学,linux上的静态库.a相当于win的.lib,动态库.so相当于win的.dll. 首先简要地解释下这两种函数库的区别,参考 ...
- linux下静态库和动态库一些东西
http://www.cnblogs.com/changefuture/archive/2011/12/22/2297460.html Linux 动态链接库和静态库示例 文件预览 文件目录树如下, ...
- Linux C 静态库(.a) 与 动态库(.so) 的详解
库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别 1.静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较 ...
随机推荐
- Makefile的补充学习
通配符%和Makefile自动推导(规则)(1)%是Makefile中的通配符,代表一个或几个字母.也就是说%.o就代表所有以.o为结尾的文件.(2)所谓自动推导其实就是Makefile的规则.当Ma ...
- Struts02---实现struts2的三种方式
01.创建普通类 /** * 01.普通类 * 写一个execute() 返回String类型值 * */ public class HelloAction01 { public String exe ...
- JavaScript能做的事 是不是jQuery都能做>?
比如修改表单中的action 并实现跳转 问题是此时没有点击表单中的submit 提交按钮?
- 【linux】打包压缩命令
打包命令:tar\zip 压缩命令:gzip 打包文件 tar -zcvf xxx/ tar -xvf xxx.tar z的意思是通过gzip压缩 c是create是生成打包的意思,x是解包 v是压缩 ...
- 探索Javascript 异步编程
在我们日常编码中,需要异步的场景很多,比如读取文件内容.获取远程数据.发送数据到服务端等.因为浏览器环境里Javascript是单线程的,所以异步编程在前端领域尤为重要. 异步的概念 所谓异步,是指当 ...
- Nodejs 实用工具集笔记
前言 工具列表 supervisor 安装 使用 node-inspector 安装 使用 SuperAgent 安装 使用 教程 cheerio 安装 使用 教程 总结 前言 学了Nodejs一天了 ...
- 如何回复在Git中误操作删除的文件?
不小心的操作,删除了某些文件 某天很高大地用上了git来管理版本,分布式版本管理工具,好是好,但是还不是很熟悉,结果某天一不小心就从本地仓库中删除了若干个文件,该如何找回这些文件呢? 调查现场 git ...
- Leetcode 999. Available Captures for Rook
class Solution: def numRookCaptures(self, board: List[List[str]]) -> int: rook = [0, 0] ans = 0 f ...
- Build ios app with Delphi Xe4. Lazy Social Talker ready for sale.
Yes, it is build with Delphi XE4. try it. now. What is Lazy Social Talker? Lazy Social Talker is a ...
- C/C++ 笔试题一
摘自 网络上的 笔试题,据说是华为的,考察的内容还算全面,也很细致: 答案 疏略 检查了下,应该没有什么大问题,但是 还是那句话,尽信之不如无,所以还是要自己思考 1.static有什么用途?(请至少 ...