动态库的制作与使用

1.动态库的命名规则

  • Linux:libxxx.so

        lib:前缀(固定的)

        xxx:库的名字(自定义的)

        so:后缀(固定的)

        在Linux下是一个可执行文件

  • Windows:libxxx.dll

2.准备工作

这里用的代码和静态库的制作用的代码是一个,只不过被我分在两个文件夹下了:

3.制作动态库

(1)得到.o文件,得到和位置无关的文件

命令格式:

gcc -c -fpic/-FPIC xxx.c xxx.c xxx.c

解释:

        -c    ——     编译、汇编指定的源文件,但不进行链接

        -fpic/-FPIC    ——      生成与位置无关的代码

        xxx.c     ——     源代码文件

我们先进入带test_code文件夹下,得到.o文件,打开终端,输入以下命令:

gcc -c -fpic add.c div.c mult.c sub.c

执行完该指令后,会生成相应的.o文件,可以用tree命令查看一下:

(2)gcc得到动态库

命令格式:

gcc -shared xxx.o xxx.o -o libxxx.so

或

gcc -shared *.o -o libxxx.so

解释:

        -shared     ——     生成共享目标文件

        xxx.o      ——      gcc得到的对应的.o文件

        -o     ——     将文件编译成可执行文件

        libxxx.so   ——   Linux环境下动态库的命名

        *.o     ——   代表所以.o文件

然后我在test/test_code目录下执行终端命令:

gcc -shared *.o -o libcalc.so

执行完后会生成一个libcalc.so的动态库文件,可以tree查看一下:

4.使用动态库

(1)将动态库复制到test/test_dynamic/lib目录下

(2)编译main.c

gcc main.c -o main -I include/ -L lib/ -l calc

执行该命令后,会生成一个main可执行文件:

(3)执行main文件(会报错)

这时候会发现报错了:

意思就是说加载动态库libcalc.so失败,虽然我们编译main.c的时候指定了动态库的路径和名称,但是生成的可执行文件在运行时找不到动态库文件。

(4)分析报错原因

  • 静态库:gcc进行链接时,会把静态库中代码打包带可执行程序中
  • 动态库:gcc进行链接时,动态库的代码不会被打包到可执行程序中
  • 程序启动之后,动态库会被加载到内存中,可通过ldd(list dynamic dependencies)命令查看动态库依赖关系
  • 当系统加载可执行文件时,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so来完成的,它先后搜索elf文件的DT-RPATH段——>环境变量LD_LIBRARY_PATH——>/etc/ld.so.cache文件列表——>/lib/ 或  /user/lib目录找到库文件后将其载入内存

通过ldd命令查看动态库依赖关系之后会发现,我们制作的libcalc.so这个动态库文件找不到!我们知道了是因为找不到动态库libcalc.so之后呀,把这个动态库的绝对路径加上不就好了。

5.解决使用动态库时的报错

5.1 法一:给LD_LIBRARY_PATH添加环境变量

(1)查看一下动态库libcalc.so的路径,并复制。使用pwd命令得到路径

(2)开始配置环境变量

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lhn/test/test_dynamic/lib

这个命令的意思就是配置LD_LIBRARY_PATH环境变量,$LD_LIBRARY_PATH是获取LD_LIBRARY_PATH环境变量之前的一些环境变量,然后用 : 隔开,开始添加新的环境变量路径。

运行这行命令没有报错,则环境变量就配置成功了!

(3)查看环境变量

  • 可以直接输入env命令查看环境变量:

这些都是系统环境变量,然后画红框的就是我们刚刚添加的环境变量,这样太多了也不好找可以用下面的方法。

  • 只查看LD_LIBRARY_PATH的环境变量

命令:

echo $LD_LIBRARY_PATH

可以看到只显示了LD_LIBRARY_PATH的环境变量,前面没有东西,就代表LD_LIBRARY_PATH之前没有环境变量,我们后来加了一个。

然后我们载查看一下main的动态库依赖关系:

可以看到,我们制作的动态库libcalc.so已经被找到了!

(4)执行main

可以看到,程序执行正确,输出结果!

注意:这是在终端里面配置的环境变量,是一个临时的,如果说我们断开连接,重新打开一个终端运行main可执行文件时,会发现又报错了,之前配置的环境变量没了。临时的还是可以用的😉

5.2 法二:用户级别的配置

(1)进入家目录下,输入ll命令:

可以看到有一个隐藏文件.bashrc,其实我们配置这个文件就可以了,直接编辑她:

  1. vi .bashrc打开这个文件
  2. 然后shift+g跳转到最后一行
  3. 输入o(往下插一行)        
  4. 将配置信息输入
  5. 保存并退出

(2)使刚刚的修改生效

. .bashrc

或

source .bashrc

这两个命令都可以,执行完不报错就可以:

(3)查看一下main的动态依赖库关系

说明libcalc.so的环境变量已经配好了!

(4)执行程序

5.3 法三:系统级别的配置

(1)配置/etc/profile

sudo vi /etc/profile

同样的操作,直接shift+g(跳转到最后一行),输入o(在下反插入一行),输入配置信息

然后保存并退出!

(2)使刚刚的修改生效

source /etc/profile

或

. /etc/profile

两个命令都可以!

(3)查看main可执行文件的动态库依赖关系

OK!显示配置成功!

(4)执行程序

OK!结束了!动态库的使用比静态库复杂一点!

6.动态库的优缺点

6.1优点

  • 可以实现进程间资源共享(共享库)
  • 更新、部署、发布简单
  • 可以控制何时加载动态库

6.2缺点

  • 加载速度比静态库慢
  • 发布程序时需要提供依赖的动态库
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值