加入收藏 | 设为首页 | 会员中心 | 我要投稿 百科站长网 (https://www.baikewang.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux中动态库(共享库)的制作与使用

发布时间:2022-09-23 16:01:02 所属栏目:Linux 来源:
导读:  0. 库的基本概念

  见博客:Linux中静态库的制作与使用

  0.1 动态库的工作原理

  首先回忆一下静态库,使用静态库,在GCC进行链接时,会把静态库中代码打包到可执行程序中。

  但是使用
  0. 库的基本概念
 
  见博客:Linux中静态库的制作与使用
 
  0.1 动态库的工作原理
 
  首先回忆一下静态库,使用静态库,在GCC进行链接时,会把静态库中代码打包到可执行程序中。
 
  但是使用动态库,在GCC进行链接时,动态库的代码不会被打包到可执行程序中,只是打包了动态库的一些信息到可执行程序中。
 
  程序启动后,动态库会被动态加载到内存中,通过ldd(list dynamic dependencies)命令可以检查动态库依赖关系。
 
  那么如何定位动态库文件呢?当系统加载可执行代码的时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取所依赖的动态库的绝对路径。对于ELF格式的可执行程序,是由ld-linux.so来完成的,它先后搜索ELF文件的:
 
  DT_RPATH段→环境变量LD_LIBRARY_PATH→/etc/ld.so.cache文件列表→/lib/或/usr/lib目录
 
  直到找到库文件,然后将其载入内存。
 
  注:ld-linux.so就是动态载入器,是专门用来负责定位、加载程序所需要的所有动态库文件。现在的Linux操作系统的可执行程序基本上都是ELF格式的。
 
  1. 动态库的命名规则
 
  在Linux系统中,动态库(共享库)的命名格式为:libxxx.so,在Linux下动态库是一个可执行文件。其中:
 
  需要注意:libxxx.so是动态库的库文件的名称,xxx是库的名称。
 
  2. 动态库的制作 2.1 动态库的制作过程 gcc得到.o文件,得到和位置无关的代码。命令格式为:
 
  gcc -c -fpic/-fPIC a.c b.cgcc得到动态库(共享库)。命令格式为:
 
  gcc -shared a.o b.o -o libcalc.so 2.2 动态库的制作过程示例
 
  首先列出名为calc的文件的树形图。我们将要在calc文件内制作动态库。
 
  在这里插入图片描述
 
  输入如下命令,进入calc目录。
 
  cd calc
  输入如下命令,得到与位置无关的.o代码。
 
  gcc -c -fpic add.c div.c mult.c sub.c
  然后输入如下命令,完成库文件名为libcalc.so的动态库的创建。
 
  gcc -shared add.o div.o mult.o sub.o -o libcalc.so
  3. 动态库的使用
 
  首先给出要使用动态库libcalc.so的名为library的文件的树形图。
 
  在这里插入图片描述
 
  上一节制作好的动态库libcalc.so位于calc文件内,而calc文件与library文件位于同一级。
 
  因此使用如下命令,将calc中的libcalc.so移动至library文件的lib文件内。其中:
 
  cp ../calc/libcalc.so ./lib/
  复制之后,如下图所示。
 
  在这里插入图片描述
 
  参照静态库的使用,我们输入如下命令,进行main.c的编译链接。
 
  gcc main.c -o main -I ./include/ -L ./lib/ -l calc
  编译链接成功后,文件内容如下图所示。可以看到,生成了名为main的可执行程序。
 
  接下来尝试着运行一下main这个可执行程序。输入:
 
  ./main
  出现如下报错
 
  检查一下错误原因:
 
  首先利用ldd命令查看一下main的动态库依赖关系。
 
  ldd main
  结果如下图所示,可以看到,动态库libcalc.so没有被找到。
 
  由0.1 动态库的工作原理可知,只要把动态库libcalc.so的绝对路径添加到动态载入器的搜索路径中,那么动态载入器就可以获取到动态库libcalc.so的绝对路径,接着就可以找到动态库文件libcalc.so,将动态库文件载入内存,然后就可以使用动态库里面的代码,最终可执行程序main就可以成功运行,不会报错。
 
  还是由0.1 动态库的工作原理可知,动态载入器搜索动态库绝对路径的搜索顺序为:DT_RPATH段→环境变量LD_LIBRARY_PATH→/etc/ld.so.cache文件列表→/lib/或/usr/lib目录
 
  因此,添加动态库绝对路径的方法也有很多种
 
  接下来,我们就按照上述分析进行操作。
 
  3.1 将动态库绝对路径添加至环境变量LD_LIBRARY_PATH 3.1.1 临时环境变量
 
  首先进入存放动态库的文件夹内linux动态库,然后输入如下命令,获取动态库libcalc.so的绝对路径,然后复制此绝对路径。
 
  pwd
  输出如下:
 
  然后输入如下命令,将动态库绝对路径添加至环境变量LD_LIBRARY_PATH中。其中:
 
  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/veroll/Linux/lesson1.6/library/lib
  输入完上述命令后,输入如下命令检查一下环境变量LD_LIBRARY_PATH的值。其中:
 
  echo $LD_LIBRARY_PATH
  输出结果如下图,可见动态库的绝对路径已经成功添加至环境变量LD_LIBRARY_PATH中了。
 
  最后再使用ldd命令查看一下main的动态库依赖关系,如下图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。接下来就可以找到动态库文件libcalc.so,然后将动态库文件载入内存,接着就可以使用动态库里面的代码,最终可执行程序main就可以成功运行了。
 
  我们来试着运行一下main。
 
  在这里插入图片描述
 
  此时main就可以成功运行了。
 
  但是这个方法有一个缺点,就是:刚才配置环境变量时,本质上是在刚才使用的终端中配置的环境变量(临时的环境变量),一旦关闭刚才的终端,再新启动一个终端,再次运行main时,就又会报错。
 
  因此最好配置一个永久的环境变量。配置永久的环境变量又有两种方法,一种是用户级别,另一种是系统级别。
 
  3.1.2 用户级别:配置永久环境变量
 
  输入命令cd或者命令cd /home/veroll/,进入用户目录(veroll)下。
 
  输入命令vim ./.bashrc,编辑.bashrc文件。其中:
 
  然后在当前模式(命令模式)下输入shift+g(也就是G)移动到这个文件的最后一行,然后输入o(小写的o),即在目前光标所在的下一行处输入新的一行,进入输入模式。

  在这里输入配置环境变量的命令export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/veroll/Linux/lesson1.6/library/lib。
 
  然后按一下esc见进入命令模式,输入命令:wq,按回车,保存并退出。
 
  接着输入如下命令,使修改生效。其中:
 
  source ./.bashrc
  如下图所示运行完此命令后,.bashrc文件的修改就生效了,也就是说环境变量添加成功了。
 
  然后进入main的目录中,使用ldd命令查看一下main的动态库依赖关系。
 
  如上图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。
 
  运行一下main。
 
  运行成功。
 
  3.1.3 系统级别:配置永久环境变量
 
  在系统级别下配置永久环境变量时,需要获取权限。
 
  在任意目录下,输入如下命令,然后输入用户密码。
 
  然后在当前模式(命令模式)下输入shift+g(也就是G)移动到这个文件的最后一行,然后输入o(小写的o),即在目前光标所在的下一行处输入新的一行,进入输入模式。
 
  (更多vim指令请见博客:Linux vi/vim命令大全)
 
  在这里输入配置环境变量的命令export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/veroll/Linux/lesson1.6/library/lib。
 
  然后按一下esc见进入命令模式,输入命令:wq,按回车,保存并退出。
 
  接着输入如下命令,使修改生效。

  使用ldd命令查看一下main的动态库依赖关系。
 
  如上图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。
 
  运行一下main。
 
  运行成功。
 
  3.2 将动态库绝对路径添加至/etc/ld.so.cache文件列表中
 
  首先输入如下命令查看一下ld.so.cache文件,并尝试对其进行修改
 
  发现是二进制文件,无法直接对其进行修改,因此需要间接修改文件内容。输入:q!,不保存直接退出。
 
  接着,输入如下命令,对ld.so.conf文件进行编辑,间接修改ld.so.cache文件内容。
 
  输入o(小写的o)进入输入模式,输入动态库的绝对路径/home/veroll/Linux/lesson1.6/library/lib。输入完成后,按下esc键,然后输入:wq,保存并退出。

  然后输入如下命令,进行更新
 
  sudo ldconfig
  进入main所在目录后,使用ldd命令查看一下main的动态库依赖关系。
 
  如上图所示,此时动态载入器就可以获取到动态库libcalc.so的绝对路径了。
 
  运行一下main。

  运行成功。
 
  3.3 将动态库添加至/lib/或/usr/lib目录
 
  如本节标题所示,直接将需要用到的动态库添加至/lib/或/usr/lib目录中,即可使用动态库。
 
  查看一下/lib/和/usr/lib目录中的内容,发现里面存放有系统的动态库文件。

  若用户自己制作的动态库文件名与系统的动态库文件名重名的话,当把用户自己制作的动态库文件移动至上述两个文件夹内,会将系统的动态库文件覆盖掉,造成损失。因此不推荐使用此方法。
 

(编辑:百科站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!