1.6动态库的制作

16 篇文章 3 订阅

一、动态库的命名规则

1. Linux:libxxx.so

  • lib:前缀(固定)
  • xxx:库的名字,自己起
  • .so:后缀(固定)
  • 在Linux下是一个可执行文件

2. Windows:libxxx.dll

二、动态库(又称共享库,是可执行文件)的制作:

1. gcc 得到.o文件,得到和位置无关的代码

gcc -c -fpic/-fPIC a.c b.c(源文件)

2. gcc得到动态库

gcc -shared a.o b.o -o libcalc.so

3. 制作过程如下:

先把环境准备好
在这里插入图片描述
得到.o文件后,再去制作动态库
在这里插入图片描述
在这里插入图片描述
x x x
ps ef :全格式显示所有进程

三、动态库的使用

library 就相当于我们的一个项目:include 下放头文件,lib目录下:将来放库文件,src目录下跟刚才生成动态库的源代码文件是类似的(正式开发的时候,其实是一些其他的源文件),main.c是测试文件;

1. 把刚才生成的动态库放入,lib目录下

在这里插入图片描述

2. 要把动态库和头文件都分发“别人 ”才能使用

动态库库文件里面是函数或者说API的具体定义,头文件里面是声明;
所以没有头文件是不能使用的,因为这样就不知道里面有哪些API

在这里插入图片描述
在这里插入图片描述
但是我们发现,执行./main,报错了,为什么?
报错信息:当加载共享库的时候,libcalc.so动态库文件,不能打开共享的文件,找不到这样的文件或者目录
这就很奇怪了,该给的信息(指定了库的名称以及库的目录),我们不是都给了吗?但是生成的可执行文件在去运行的时候,找不到动态库文件。
在如何解决这个问题之前,我们得先了解动态库具体实现以及加载的原理;

3. 了解动态库具体实现以及加载的原理(工作原理)

(1)静态库与动态库的工作原理

  • 静态库(静态库中都是目标/二进制代码):GCC进行链接时,会把静态库中代码打包到可执行程序中;
  • 动态库:GCC进行链接时,动态库的代码不会被打包到可执行程序中;(只会把动态库的一些信息放入到可执行程序中【并不会加载动态库的内容到内存中】,所以我们在运行可执行程序时,要是用到了动态库【使用了动态库中的API时,就会查找动态库的绝对路径,找到后加载到内存中】,在可执行程序中是找不到动态库的代码的,所以会报加载动态库失败这个错误)
  • 在程序启动之后,应用了动态库(程序要想运行,首先要加载到内存当中,那么使用到了动态库的内容,就得把动态库的内容一起加载到内存中),就得把动态库先加载到内存中,才能使用;
  • 通过ldd(lsit dynamic dependencies 列出动态依赖)命令检查动态库依赖关系;
  • 在这里插入图片描述

(2)可执行程序运行起来是怎么去找这些动态库的?

  • 如何定位共享库文件呢?
    • 当系统加载可执行代码时,能够知道其所依赖的库的名字,但是还是需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径(加载的时机:当我们的程序调用了动态库的一些API时,那就会去加载。)。对于elf格式的可执行程序,是由ld-linux.so(动态载入器)来完成的(来获取动态库的绝对路径,是有先后顺序的),它先后搜索elf文件的DT_RPATH段(我们一个程序运行起来就是一个进程,Linux会为每个进程分配虚拟地址空间,而这个DT_RPATH段是在虚拟地址空间中,若我们没有动态库的路径放进去DT_RPATH段填充的话,是找不到的,而这个DT_RPATH段我们也修改不了,若是找不到,接着我们看下一个)->环境变量LD_LIBRARY_PATH(若是这个环境变量配置了动态库的完整路径的话,动态载入器就会根据这个路径,将动态库完整的加载到内存中,若没有的话,接着往后面找)->/etc/ld.so.cache文件列表->/lib/或者/usr/lib目录找到库文件后将其(动态库内容)载入内存。
    • 在这里插入图片描述

4. 解决动态库加载失败问题

(1)方法一:export添加环境变量

方法一:export添加环境变量
在这里插入图片描述
这个时候就能查找到了在这里插入图片描述
执行也不报错了 在这里插入图片描述
但是,方法一,这种方式有一个弊端,当我们关闭当前连接,再次打开一个终端后,再去执行./main就会报错了,原因是因为,刚才配置的环境变量是在终端去配置的,当我们关闭这个终端,重新打开一个终端后,这个环境变量就消失了(临时);所以我们应该永久的去配置这个环境变量。(用户级别的配置和系统级别的配置)
在这里插入图片描述

(2)方法二:用户级别的配置

step one : 先进入home目录下;
在这里插入图片描述
step two : vim .bashrc
在这里插入图片描述
step three : 拼接上我们创建的动态库的绝对路径
在这里插入图片描述
step four : 保存退出后,要使刚才的配置生效
两种语句:. .bashrc;或者source .bashrc
step five : 执行./main

(3)方法三:系统级别的配置

先把之前用户级别的配置删掉再重新生效
在这里插入图片描述
step one : sudo vim /etc/profile【sudo … 提权】
在这里插入图片描述
配置在这里插入图片描述
step two : source /etc/profile
在这里插入图片描述

(4)方法四:修改/etc/ld.so.cache文件列表

首先,还是先清除刚才的配置,不然看不出效果;注意注意,要是感觉删除配置取消不了影响,就试一下生效source完之后,重新连接虚拟机,再打开一个窗口;
one : ll /etc/ld.so.cache (先观察一下)
在这里插入图片描述
two : vim /etc/ld.so.cache【它里面都是二进制的数据,不允许编辑,所以我们不能直接修改它,而是间接修改它】
在这里插入图片描述
three : sudo vim /etc/ld.so.conf,然后在这个文件中加入路径
在这里插入图片描述
four : 进行配置的更新:sudo ldconfig
在这里插入图片描述
生效完就可以找到了;

(5)方法五:将动态库放入/lib或者/usr/lib目录下,也是可以找到动态库的(不建议使用这种方法,因为这两个目录下包含了很多系统自带的库文件,所以避免引起麻烦就不要用这种方法了)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值