【Linux】动静态库

简单了解一下库

静态库(.a:程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静
态库
动态库(.so:程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文
件的整个机器码
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个
过程称为动态链接(dynamic linking)
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚
拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
库命名: libcrack.so.2该库的名字是crack,先去掉前缀lib在去掉第一个点后面的内容。
一般云服务器只会默认存储动态库,不存静态库,静态库需要独立安装。

简单创建库理解

静态库

将头文件和.o文件进行打包,然后将.o创建成静态库。然后编译的时候要指定头文件和库文件路径,还要指定库文件名字(去前缀和后缀的库名)。
在这里插入图片描述

[root@localhost linux]# ls
add.c add.h main.c sub.c sub.h
[root@localhost linux]# gcc -c add.c -o add.o
[root@localhost linux]# gcc -c sub.c -o sub.o
生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o 
ar是gnu归档工具,rc表示(replace and create)
查看静态库中的目录列表
[root@localhost linux]# ar -tv libmymath.a 
rw-r--r-- 0/0 1240 Sep 15 16:53 2017 add.o
rw-r--r-- 0/0 1240 Sep 15 16:53 2017 sub.o
t:列出静态库中的文件
v:verbose 详细信息
[root@localhost linux]# gcc main.c -L. -lmymath
-L 指定库路径
-l 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行

上面的方法是将头文件和库防止在当前路径或者其他路径是需要指向的要不然找不到。
而当我们分别将头文件放到usr/include路径下,库放到/lib64路径下,这两个路径是属于系统的默认路径
在编译时就不需要指定路径了,只需要指向一下库名就可以了

第三方库的使用
1、需要指定头文件和库文件
2、如果没有默认安装到gcc\g++的默认搜索路径下,需要指明对应的选项 -I(头文件) -L(库文件) -l(库名)
3、在Linux下安装库,就是将头文件和库拷贝到系统的默认路径下。(卸载和安装的道理是一样的)
4、如果安装的库是第三方的(就是非语言、操作系统接口的)库,即便是安装到了系统默认搜索的路径下仍是需要指明库名的(l),安装到系统中的库大部分是都需要sudo或超级用户操作。

动态库

库搜索路径
从左到右搜索-L指定的目录。
由环境变量指定的目录 (LIBRARY_PATH)
由系统指定的目录
/usr/lib
/usr/local/lib
生成动态库
shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
示例:
[root@localhost linux]# gcc -fPIC -c sub.c add.c
[root@localhost linux]# gcc -shared -o libmymath.so *.o
[root@localhost linux]# ls add.c add.h add.o libmymath.so main.c sub.c sub.h sub.o
使用动态库
编译选项
l:链接动态库,只要库名即可(去掉lib以及版本号)
L:链接库所在的路径.
示例: gcc main.o -o main –L. -lhello
运行动态库:
1、像前面的静态库一样将.o.h进行打包,但是这里的形成.o文件有所不同,需要加上fPIC产生位置无关码,并且形成动态库的方法变成了使用gcc,然后像静态库一样运行却发现不行,使用了I L l也是不行的,报错是找不到该文件。原因是我们上面告诉的是编译器,并不是系统,这里是系统找不到文件,但是为什莫静态库就可以找到呢?原因:他的链接原则是将用户使用的二进制文件直接拷贝到目标可执行文件当中。动态库就不会。
2、os如何查找动态库
先介绍一条命令ldd 可执行文件它是用来查找可执行文件依赖第三方库的一条命令。
(1)第一种方法是添加环境变量(但是是一种临时方案)export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:加上库的路径
(2)第二种方法是在系统默认路径下创建一个软连接
sudo ln -s /home/zzm/test/lesson23/libmymath.so /lib64/libmymath.so
(3)第三种方法配置文件方案/etc/ld.so.conf.d/在该条路径下创建个文件,将自己准备用的库的绝对路径拷贝到新创建的文件里,这里因为是OS所以需要sudo或者超级用户,然后再输入ldconfig使其立刻生效。

静态库:就是将.o二进制文件直接拷贝到可执行文件当中
动态库:是通过类似传指针的方法,将库加载到内存,就只需要一份,然后每个可执行文件都会带上库的偏移量,在虚拟地址当中存储一个准确的地址,再加上偏移量就可以连接到库了。
在这里插入图片描述
在这里插入图片描述
所以在前面说的与位置无关码:动态库中地址,都是偏移量
动态库和静态库同时存在优先使用动态链接,在编译时的结尾加上-static就会使用静态库
file命令

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值