关于动态库的的编写与使用过程

11 篇文章 0 订阅

动态库相关

在实习期间做的事情是对组内项目编译的辅助工具编写,期间涉及到很多关于动态库相关的一些内容,现在将动态库相关的一些知识来整理和重新学习一下,目前只考虑Linux环境

什么是动态库

说动态库之前要来看一下什么是"库",库是一系列可复用,成熟的,已经写好的代码,动态库是使用非常多的一种技术,动态库在程序运行的时候被载入(静态库是编译时),不同的程序调用相同的库的时候,内存中只存在一方该shared库的实例,相对于静态库来讲,动态库节约了空间资源,也使得部署的服务或应用在更新的时候变得十分轻量化(最开始下载游戏可能需要下载好几个G,但是玩了一段时间发现要更新下载的内容就十分少量,这就是应用了动态库的技术使得用户得到了更好的体验)

创建动态库的方法(Linux)

在Linux下gcc编译的执行文件默认的ELF格式,不需要初始化入口,也不需要对函数进行特别的声明,直接编写即可,十分方便。
例子:

//math.h
  1 #ifndef __MATH_H__
  2 #define __MATH_H__
  3 
  4 void Add(int x, int y);
  5 
  6 void Sub(int x, int y);
  7 
  8 void Mul(int x, int y);
  9 
 10 void Div(int x, int y);
 11 #endif

//math.cc
  1 #include <iostream>
  2 #include "math.h"
  3 
  4 void Add(int x, int y)
  5 {
  6     std::cout<<x<<" + "<<y<<" = "<<x+y<<std::endl;
  7     return;
  8 }
  9 
 10 void Sub(int x, int y)
 11 {
 12     std::cout<<x<<" - "<<y<<" = "<<x-y<<std::endl;
 13     return;
 14 }
 15 
 16 void Mul(int x, int y)
 17 {
 18     std::cout<<x<<" * "<<y<<" = "<<x*y<<std::endl;
 19     return;
 20 }
 21 
 22 void Div(int x, int y)
 23 {
 24     if(y == 0)
 25         return;
 26     else
 27     {
 28         std::cout<<x<<" / "<<y<<" = "<<x/y<<std::endl;
 29     }
 30 }

对要生成的动态库进行编译,用g++ -fPIC -shared 编译

[root@localhost MathLib]# g++ -fPIC -shared -o libmath.so math.cc 
[root@localhost MathLib]# ls
libmath.so  math.cc  math.h

生成了动态库libmath.so文件。

如何使用动态库

直接引用动态库的头文件,在编译的时候加上 -L指定动态库的路径,-l指定动态库的文件名
实例程序:

  1 #include "MathLib/math.h"
  2 
  3 int main()
  4 {
  5     Add(1, 2);
  6     Sub(2, 1);
  7     Mul(2, 2);
  8     Div(2, 1);
  9     return 0;
 10 }

编译:

[root@localhost test_for_lib]# g++ test.cc -L./MathLib -lmath
[root@localhost test_for_lib]# ls
a.out  MathLib  test.cc

其中要注意的地方就是对于.so文件在 -l的时候,要省略前边的lib和后边的.so字段,比如库名为 libmath.so 就写 -lmath就ok了。

运行程序:

[root@localhost test_for_lib]# ./a.out 
./a.out: error while loading shared libraries: libmath.so: cannot open shared object file: No such file or directory

直接运行./a.out会报错,因为系统在加载代码的时候能知道所依赖的库的名字,但是还需要知道绝对路径,这时候就需要 系统动态载入器(dynamic linker/loader),对于elf格式的可执行程序,是由ld-linux.so*来完成的,他先搜索elf文件的DR_RPATH段一环境变量LD_LIBRARY_PATH-/etc/ld.so.cache文件列表-/lib/ 或者 /usr/lib/ 下来找到库文件将其载入内存,所以当库安装在/usr/lib/ 或者 /lib/目录下的时候ld默认能直接找到,不需要做其他的操作,若是将其安装到其他的目录地下需要编辑 /etc/ld.so.conf 文件 include 库的绝对路径(到目录层面即可),再运行 ldconfig 来重建 /etc/ld.so.cache文件即可运行起来了

[root@localhost test_for_lib]# ldconfig
[root@localhost test_for_lib]# ./a.out 
1 + 2 = 3
2 - 1 = 1
2 * 2 = 4
2 / 1 = 2

这样就完成了一个简单的动态库的编写与使用过程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值