实现自己的静态链接库与动态链接库

29 篇文章 0 订阅

静态链接库是指在源代码中调用库中的函数,被编译为.o目标文件后,再链接上库文件,形成可执行程序。

库文件是多个.o目标文件的合并,它们存放着包括各个函数的定义在内的信息,最终被一起链接进可执行程序。

那么在运行期之前,可执行程序中就包含所有程序运行的条件,也就是所谓的静态链接。

 

首先,新建两个.cpp文件  add.cpp sub.cpp 它们中都定义了两个简单的函数

g++ -c add.cpp sub.cpp

生成如下2个对象文件 add.o  sub.o

进一步,通过nm命令查看该.o文件

 

可以看到  .o文件中存放了函数符号的定义(编译器丰富了函数标识符(函数名))

通过linux中ar命令  来生成静态链接库文件   其中参数 c表示创建  r表示插入

(注意库文件一般命名为 lib***.a  因为g++在编译链接时,采取前后缀查看库文件)

ar -cru libtest.a add.o sub.o

生成的libtest.a 即为库文件,通过nm命令查看发现其实为 多个.o目标文件的合并 

 

先声明一个my_lib.h文件,里面只存放函数的声明,.h头文件不直接参与编译。而是在预处理时被文本包含进源文件。

int add_fun(int,int);
int sub_fun(int,int);
//声明

在main.cpp内容如下:    

#include<stdio.h>
#include"my_lib.h"
int main()
{
	printf("%d\n",add_fun(3+2));
	printf("%d\n",sub_fun(3-2));

}

通过g++ 联合静态库文件进行编译链接,指令如下:

g++ main.cpp  -L. -ltest  -o main

其中-L表示(link)其后跟需要link的目录,默认在/usr/lib   而 -l 紧跟着test表示需要链接库 test

输出如下:

 

由此可见,静态链接库,其本质就是各个.o 目标文件的集合,通常我们的程序引入静态链接库时流程如下:

 

  1. 首先包含链接库所声明的头文件,头文件存放定义,确保我们的源文件能够通过编译
  2. 将源文件编译为目标文件后,库文件是多个目标文件集合,相互链接后即可生成最终的可执行文件

 

因此静态链接库的特点如下:

  • 每个使用静态链接库的程序都需要一份库文件相互链接形成可执行文件,即静态链接后可执行文件较大
  • 一旦库文件发生更改,需要重新进行链接,以生成新版本的可执行程序,不易于更新
  • 可执行程序为目标文件和库文件连接而成,是一个完整的整体,可以独立运行

 

 

 

动态链接库:

为了解决静态链接中由于包含库文件带来的空间占用大,更新困难,复用能力低的缺点,引入动态链接概念,它的特点如下:

  • 允许可执行程序调用不属于本程序中的函数方法。
  • 同时多个进程程序可调用同一个动态链接库中的函数方法。

 

演示:

前面的add.cpp sub.cpp 联合编译为一个 libtest.so 动态链接库,链接库的名字为 test(前缀为lib  后缀为.so)

g++ add.cpp sub.cpp -fPIC -shared -o libtest.so

其中-shared 指明将其编译为共享的动态链接库。   -o 指明生成的文件,可以看到其与一般编译链接到生成可执行文件过程是相同的,只是添加 -shared指明其为共享动态链接库。一般的命名规则为 lib***.so

 

通过g++ 命令编译生成可执行文件,-ltest指明需要的动态链接库

g++ main.cpp -L. -ltest -o main_dynamic

可以看到,这个编译连接生成可执行命令和静态链接生成过程g++参数一样,不同的实现可能是编译器发现test为.so结尾也就是动态链接库。直接执行 ./main_dynamic 发现出错,信息如下:

无法加载libtest.so无法加载动态链接库,解决方法:

进入 /etc/ld.so.conf.d   即.so 动态链接库 配置项

添加一个目录到.conf文件,引入自己所在包目录

更新config

sudo lpconfig

cd

./main_dynamic

最终执行结果:

 

动态链接库的特点:

①在编译链接生成可执行文件时,可执行程序不包含完整的各个函数的定义,只有当到达运行期时,才会根据需要加载动态链接库,并进行调用。

②多个进程可调用处于内存中的同一份动态链接库,某种程度上看,动态链接库更像是一个常驻内存的进程,提供给其它使用动态链接库的程序调用。

③因此,使用动态链接库的程序具有可执行文件较小,同时由于可执行文件与动态链接库分离,因此动态链接库的更新时,可执行文件并不需要更新。由此带来的一个缺点是,单独的可执行文件不能运行。

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值