13-3 动态链接库的编译和使用

1. 静态链接库与动态链接库

        由于静态链接库不能共享,且依赖的符号的对应目标文件与主程序文件需要一同编译,故静态链接库内存空间占用较大。而动态链接库具有共享性质,通过特定路径即可引用,可以有效减少内存空间的占用

        此外,可使用 ldd 命令查看一个可执行程序所依赖的动态链接库

 2. 编译动态链接库

        以主程序文件 03.shared_library.c 为例,编译运行时需要的动态链接库,便于后续外部函数的执行。此主程序文件与上一小节的主程序文件内容相同。

#include <stdio.h>

#include "mathutils/include/factorial.h"
#include "mathutils/include/fibonacci.h"

int main(){

  printf("Factorial(4): %d\n", Factorial(4));
  printf("Fibonacci(8): %d\n", Fibonacci(8));

  return 0;
}

         编译动态链接库的具体流程为

                1)准备工作,创建 mathutils 文件夹及相应的 .h 头文件和 .c 文件。

                2)将主程序文件 03.shared_library.c 中引用的外部函数的所在 .c 文件(factorial.c fibonacci.c)编译为动态链接库。在 Linux 系统中,输入 gcc -shared -fPIC factorial.c fibonacci.c -o libmathutils.so,即可生成动态链接库 libmathutils.so。而在 Windows 系统中,需要额外添加导入库参数才能生成动态链接库。整体代码为 gcc -shared -fPIC -Wl,--out-implib,libmathutils.a factorial.c fibonacci.c -o libmathutils.dll,生成动态链接库 libmathutils.dll。

                -shared 参数表示生成共享库,即动态链接库。-fPIC 参数用来生成与地址无关的代码。因为动态链接库编译时无法确定符号运行时的地址,只能基于全局偏移表给出相对位置,而全局偏移表只能等到程序加载运行时才能确定。

              此外,可使用  ar t 命令查看导入库内部的文件,使用 objdump -t 命令查看动态链接库内部的文件。可以发现此处的导入库文件内部与上一小节的静态链接库内容不同,且动态链接库中存在 Factorial() 和 Fibonacci() 函数的相关内容。(grep 用来查找指定格式的字符串,其使用方法见:https://www.cnblogs.com/yychuyu/p/13624485.html

3. 使用动态链接库

        动态链接库编译完成后,主程序文件需要使用动态链接库进行程序的编译和执行。具体流程如下:

                1)编译主程序文件,注意参数 -Lmathutils -lmathutils。其中 -L 连接的是动态链接库路径 mathutils-l 连接的是动态链接库名称 libmathutils,但由于 lib 通常省略,故为 mathutils。

                 2)此时若直接执行 03.shared_library,其结果会如下图所示:无法找到动态链接库 libmathutils.dll。其原因在于执行程序时并未指定动态链接库的路径(编译时指定了路径)。Windows 系统下动态链接库的默认查找逻辑为:首先在当前目录下找寻待使用的动态链接库,如果未找到,则去系统的 path 路径下去找。此处 libmathutils.dll 在 Chapter13/mathutils 文件夹中,而执行程序在 Chapter13 文件夹中,故无法找到相应的动态链接库。

                 解决方法为跳转至 mathutils 文件夹下执行 03.shared_library 程序,其结果为:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值