我们指定C程序从代码到一个可执行程序需要经过预处理、编译、汇编、链接。而最后一步链接又分为动态链接与静态链接。静态链接相当于就是讲所要链接的库提前放入链接的文件,这样子的文件体积较大,但是可移植性较高。而动态链接是在运行的时候才去主动链接所需要链接的库,这样的代码体积较小,多个程序共同使用库的代码。我们LInux运用的是动态链接。
为了方便我们在接下来的内容中测试静态库与动态库,我们编写一个简单的库。
//add.h
#pragma once
int add(int a, int b);
//add.c
#include "add.h"
int add(int a, int b)
{
return a+b;
}
//add.h
#pragma once
int sub(int a, int b);
//add.c
#include "sub.h"
int sub(int a ,int b)
{
return a-b;
}
这里我们写了一个简单的加与减的库,便于后续的操作。
静态库的使用操作
生成静态库
我们生成好静态库以后这个时候进行测试,我们写一个代码将静态库链接到其中,然后删除掉这个静态库,链接过后的程序是否能够运行成功。
链接静态库并使用
我们发现当我们将自己的静态库链接到test.c文件后,生成了可执行文件a.out,然后删除掉我们的静态库,也就是libmymath.a文件,这时候运行可执行文件a.out发现是可以运行的,这说明我们的静态库在链接过后,由操作系统直接将库里的内容链接至目标文件,所以我们删除掉自己的库后文件照样可以运行成功。在生成静态库的时候ar -rc
其中ar是归档工具,rc表示replace and create。在进行链接的时候,-L
选项后加静态库的路径,-l
后加所要链接静态库的名字,静态库文件的后缀是.a
动态库
生成动态库
这里我们同样利用之前写的库来建立自己的动态库。
这里 -fPIC
目的是产生位置无关码,即文件在任何路径任何位置都可以链接到这个动态库,那么就需要经过特殊处理,这个选项目的就是这个。shared
表示生成共享库的格式,也就是类似于动态库的共享原则,所有文件都可链接。
使用动态库
编译选项:
- l:表示所要链接的动态库(去掉lib以及版本号)
- L:表示链接路径
我们发现,在将动态库链接成功生成可执行文件test以后并不能够运行。这是因为动态库链接时搜索的时候在其默认的路径下搜索,而此时我们的动态库路径并不在这个默认的路径下,所以这时候我们利用export
来导入到这个默认的路径。
如上图,导入以后再利用gcc
进行链接动态库,那么这个时候就可以运行了。
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!