反转基因福娃 发表于 2024-11-3 07:02:57

【Linux】动态库、静态库

https://i-blog.csdnimg.cn/direct/4f61b1b10cb5490eb708d880b9ee9d91.gif#pic_center
1. 概念

库的本质就是.o文件的集合。


[*]静态库:是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比力大,但在运行时也就不再必要库文件了,其后缀名一般为“.a”。
[*]动态库:是指在编译链接时并没有把库文件的代码加入到可执行文件中,而是在步伐执行与运行时链接文件加载库,这样可以节省体系的开销,动态库一般后缀名为“.so”,完成了链接之后,gcc 就可以生成可执行文件。
2. 制作静态库

预备工作
https://i-blog.csdnimg.cn/direct/d36daabdc66847b4ac83a2846e2443b2.png
在制作库时,通常要将源文件潜伏起来,只提供对应的.o文件,而且必要对.o文件进行打包
   静态库库名规则:libxxx.o
打包的命令: `ar-rclib库名.a   要打包的.o文件`
其中ar = archive(存档),r = replace,c = create;如果库中已经存在同名的.o就进行替换,没有则创建。
https://i-blog.csdnimg.cn/direct/0122b547d87e40fa937c1ee7221d11e6.png
将来,我要把库给别人用,只必要把头文件给他,把库文件给他即可。
2.1 将库安装到体系

那能不能将我自己写的库安装到体系里呢? - -直接拷贝即可。
https://i-blog.csdnimg.cn/direct/68eed5277d4440e8abbd6fd05eb67f50.png
现在,我就直接可以使用我自己写的库了
https://i-blog.csdnimg.cn/direct/fc667bff2f714ab790e4f3bd5104a1b8.png
但是链接时为什么出错呢? - -没有指定库
   选项 -l :引入指定名称的第三方库
https://i-blog.csdnimg.cn/direct/09b7010d1c604ea1871f5927d072a57f.png
2.2 将库与头文件直接拷给用户

https://i-blog.csdnimg.cn/direct/539b7ed1d1854dbb9d168c631b201b8a.png
但是此时链接又找不到库了
https://i-blog.csdnimg.cn/direct/04e61a53370e43d09cd8e63729c591dc.png
   选项:-L 库路径 - l 库名
https://i-blog.csdnimg.cn/direct/b4c97cf366534b79abe18f4d1ee2bce4.png
此时,该种方式也就能跑起来了。
2.3 使用带路径的库

https://i-blog.csdnimg.cn/direct/f9ad59e2dada4d36a88f31e9ef05108a.png
此时,我们就可以将生成的库mystdc交给别人了。那别人怎么用呢?
https://i-blog.csdnimg.cn/direct/8f0ac2e5d8ef4d20b52c38b782e13572.png
选项:-I,指定头文件的路径
   总结
-l:指定库名
-L:指定库地点的路径
-I:指定头文件的路径
3. 制作动态库

   动态库的库名规则:libxxx.so
在我们使用gcc编译时,默认形成的是可执行文件,当前如果想形成库,必要加选项 -shared
gcc -o 目标库 源文件`-shared`
在形成动态库所必要的.o文件时,必要设置与位置无关码选项 -fPIC
gcc `-fPIC` -c .o.c
https://i-blog.csdnimg.cn/direct/c03dbf376b03491f85723aad70caecd2.png
此时,我们的动态库就做好了。如果想给用户使用,仍旧可以用静态库中使用的三种方式。
下面使用将库拷贝到体系中
https://i-blog.csdnimg.cn/direct/af20b7a7d2a4499b895eef27bd918943.png
此时别人就可以使用了
https://i-blog.csdnimg.cn/direct/98bbc3ae64a447fd87c3dd2f818a67f7.png
对于动态库,我们可以使用下令 ldd 可执行文件名,查询一个可执行步伐依靠哪些库
https://i-blog.csdnimg.cn/direct/f8f9ad891c744974a51826f215c27735.png
动态库删除后步伐就不能跑了
https://i-blog.csdnimg.cn/direct/e487af890ce743d88214f6c3d8e59b21.png
为什么用户使用output后的动态库,编译器可以编过,但是运行不了可执行了呢?
https://i-blog.csdnimg.cn/direct/a5b39cc241434c3497a8f2e900bc3145.png
在gcc编译时,指定各种选项,是告诉编译器去哪里找;在运行时,操作体系要加载步伐,但是它找不到动态库了,因此报错了。
所以,动态库是必要加载的
那么如何给体系指定路径,让库被加载呢?

[*]直接将动态库拷贝到体系中
[*]在体系路径下创建动态库的软毗连
链接名肯定要和动态库的名字雷同
https://i-blog.csdnimg.cn/direct/ced008c3a2b5460ab81edba94b6398d3.png
https://i-blog.csdnimg.cn/direct/207d0f8d45744c119b8dd052986dafd3.png

[*]将自己的库路径添加到环境变量列表中
   此时对第二种方式有一个疑问:为什么你体系默认就去lib64中找呢?
因为linux中,体系查找动态库,体系存在一个环境变量 LD-LIBRARY_PATH
https://i-blog.csdnimg.cn/direct/1729ee5ec1524ab28d7de5b2b20b5859.png
那么此时,我们就可以将自己库的路径导进环境变量中!
https://i-blog.csdnimg.cn/direct/c7ce4837b5a3430d925bf83d792fe864.png

[*]设置/etc/ld.so.conf.d/,ldconfig更新
将库路径写在 etc/ld.so.conf.d目录下,该目录下存放的是一系列的设置文件,这些设置文件用于指定体系的共享库(动态链接库)搜刮路径,这些设置文件通常以.conf作为文件后缀。
https://i-blog.csdnimg.cn/direct/f1b8b547f8f549ca9976110fb03a5b4d.png

[*]如果同时给应用步伐提供动态库和静态库,它会使用哪一个呢?
gcc/g++优先使用动态库
https://i-blog.csdnimg.cn/direct/420f193152b44820a9145c6b2709be8b.png

[*]如果非得使用静态库,可在编译选项中加上-static
https://i-blog.csdnimg.cn/direct/83dd1c8808e34183b04aaaf9b49e274f.png

[*]如果强制静态链接,必须提供对应的静态库
[*]如果只提供静态库,但链接方式是动态链接的,gcc/g++没得选,只能阵对你的.a局部性接纳静态链接
4. 明白动态库

因为动态库也都是文件,那么在运行时,也会被加载到内存中。
但进程是如何看到加载的动态库呢? - -经过页表的映射,将加载到内存的动态库的地点映射到进程地点空间中的共享区
https://i-blog.csdnimg.cn/direct/6a0c88ed30d241409c5013d6df838af7.png
多个进程依靠同一个动态库时,动态库也只必要加载一份;仅必要修改其它进程页表中动态库的映射即可,所以动态库才叫做共享库。
https://i-blog.csdnimg.cn/direct/1138d3343feb46858a4b0f3616c1775c.jpeg#pic_center

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Linux】动态库、静态库