一、什么是库

本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件;对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库。

二、静态库

1、概念

静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之所以叫做静态,是因为静态库在编译的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。

2、特点

(1)静态库对函数库的链接是放在编译时期完成的。
(2)程序在运行时与函数库再无瓜葛,移植方便。
(3)浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

3、Linux下创建和使用静态库

1)Linux静态库命名规则

Linux静态库命名规范,必须是”lib[your_library_name].a“:lib为前缀,中间是静态库名,扩展名为.a

2)创建静态库(.a)

(1)首先,将代码文件编译成目标文件.o(StaticMath.o)

c动态库和ios交互_c动态库和ios交互


再利用ar工具将目标文件add.o sub.o mul.o div.o打包成静态库文件.a(注意命名规则,我的静态库文件名为:libmymath.a)

c动态库和ios交互_动态库_02


(2)这样一个静态库就创建成功了,可以利用 ar -tv libmymath.a命令查看静态库目录:

c动态库和ios交互_c动态库和ios交互_03


(3)Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L选项)、指定静态库名(不需要lib前缀和.a后缀,-l选项)。并且运行生成的./a.out 文件就可以得到结果:

c动态库和ios交互_c动态库和ios交互_04


(4)进一步可以删除静态函数libmymath.a,然后运行main函数,看看其是否真的链接到了目标函数.

c动态库和ios交互_c动态库和ios交互_05

二、动态库

1、概念

动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来。

2、特点

(1)动态库把对一些库函数的链接载入推迟到程序运行的时期。 
(2)可以实现进程之间的资源共享。(因此动态库也称为共享库)
(3)将一些程序升级变得简单。
(4)甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。

3、动态库的创建和使用

1)linux动态库的命名规则

动态链接库的名字形式为 libxxx.so,前缀是lib,后缀名为“.so”。
(1) 针对于实际库文件,每个共享库都有个特殊的名字“soname”。在程序启动后,程序通过这个名字来告诉动态加载器该载入哪个共享库。
(2)在文件系统中,soname仅是一个链接到实际动态库的链接。对于动态库而言,每个库实际上都有另一个名字给编译器来用。它是一个指向实际库镜像文件的链接文件(lib+soname+.so)。

2)生成动态库

shared:表示生成共享库格式
fPIC:产生位置无关码(position independent code)
一般生成动态库有两步:
(1)生成目标文件,此时要加编译器选项-fPIC。【ps:-fPIC是创建与地质无关的编译程序,是为了能够在多个应用程序间共享】
(2)生成动态库,此时要加链接器选项-shared。【ps:-shared是指定生成动态链接库】

3)实例

按照动态库生成步骤,就生成了libmymath.so 动态库文件:

c动态库和ios交互_c动态库和ios交互_06


使用动态库:

l:链接动态库,只要库名即可(去掉lib及版本号)

L:链接库所在路径

c动态库和ios交互_c动态库和ios交互_07


运行动态库

1、拷贝.so文件到系统共享路径下,一般指/usr/lib

2、更改LD_LIBRARY_PATH

c动态库和ios交互_c动态库和ios交互_08


删除动态库

当动态库文件被删除时,运行main,运行失败,说明程序在运行的时候才链接动态库的代码

c动态库和ios交互_静态库_09

三、总结

二者的不同点在于代码被载入的时刻不同

(1)静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大
(2)动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在,因此代码体积较小。