我们先来看两个问题:
库是什么?
答:库里面存放的是现成的,写好的,可以复用的代码,我们写的每一个程序都是报了头文件了,这些头文件里面就是一些库函数。
静态库和动态库?
答:首先静态/动态说的是链接方式。
静态链接是在程序编译时将汇编生成的目标文件与引用的库一起链接打包到可执行文件中。
动态链接是在编译时并不会被链接到目标代码中,而是在程序运行时才被载入。
动态库和静态库的区别?
答:对于静态库:
① 静态库对函数库的链接是放在编译时期完成的。
② 程序运行时与函数库再无联系,移值方便。
③ 浪费空间和资源,因为所有相关的目标文件与相关的函数库被链接合成一个可执行文件。
对于动态库:
① 动态库把对一些库函数的链接载入推迟到程序运行的时期。
② 可以实现进程之间的资源共享。(因此动态库也称为共享库)
③ 将一些程序升级变得简单。
④ 甚至可以做到链接载入完全由程序员在程序代码中控制(显式调用)。
那么接下来我们看看在Linux下如何打包动/静态库,以及如何使用!!!
本文所有程序都在CentOS Linux release 7.3.1611运行!
先看看我们的程序文件,我们的程序主要分为四则运算的头文件和定义文件,以及我们的main文件
arithmetic.c
arithmetic.h
main.c
动态库
首先我们来打包一个动态库, 首先库中存放的是我们的目标文件,将我们生成的目标文件打包。
所以第一步:先生成目标文件:
在生成动态库这里的目标文件时,我们要注意使用 -fPIC 选项生成位置无关代码。这是为了能在多个应用程序中共享这个共享库。
第二步: 生成动态库
我们这里使用的是一个 - -share 选项,用于生成动态库,
因为动态库也是一个共享库,所以是share(我猜的,啊哈哈)
此时动态库已经生成了,我们的libmy_ari.so就是我们生成的动态库,其中lib是前缀,.so是后缀,my_ari是我们的动态库名称。
接下来就是使用动态库了:
使用库就很简单了,将我们的main函数生成可执行文件并链接我们生成的动态库。
使用gcc -main.c -o main -l库名称
欸?!?按照要求链接我们的库了,但是竟然找不到这个库?这是为什么呢?
这是因为我们链接库的默认路径是在/lib64/下的,而我们的库是在我们当前目录下,所以链接不到,这样很简单,我们将我们生成的库放入/lib64/下就行了。
这样成功链接到我们的动态库,然后生成了可执行文件,我们执行它!!!
得到我们想要的结果,证明成功连接到我们的库了
动态库我们搞定了,接下来看看静态库是如何生成的!
静态库的生成及使用
第一步:还是生成目标文件
第二步:我们使用 ar 命令生成我们的静态库:
此时静态库也已经生成了,我们的libmy_ari.a就是我们生成的动态库,其中lib是前缀,.a是后缀,my_ari是我们的静态库名称。
第三步同样是先把我们的库放入/lib64/下,然后链接即可
我们这里使用了 cr,cr 是静态库链接器,是用于生成静态库的,其中-c选项是创建静态库,-r是模块替换。
有人可能会想到,gcc不是有一个-static选项吗?这不是链接静态库的吗?
解释一下:因为gcc默认链接的是动态库,如果我们直接使用gcc -static main.c -o main -lmy_ari 也是错误的,因为系统下大部分都是动态库,所以就算我们将生成的静态库放入/lib64/下也是不行的,所以我们使用gcc main.c -o main -lmy_ari 用来指定库的查找路径。(前提是得有静态库)
在这里说下库的后缀:
在Linux下:
.so 是动态链接库
.a 是静态链接库
在Windows下
.dll 是动态链接库
.lib 是静态链接库