库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a/.lib
)和动态库(.so/.dll
)。
【静态库】 在链接阶段,将汇编生成的目标文件.o与引用的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
1)静态库对函数库的链接是放在编译时期完成的;
2)程序在运行时与函数库再无瓜葛,移植方便;
3)浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
ar -参数 libxxx.a archive files (.o文件)
注:xxx是指自己创建的静态库名
参数 | 参数含义 |
---|---|
-c | 建立库文件 |
-r | 将文件插入库文件中 |
-o | 保留库文件中文件的日期 |
-v | 程序执行时显示详细的信息 |
-d | 删除库文件中的成员文件 |
-m | 变更成员文件在库文件中的次序 |
首先,将代码文件编译成目标文件.o(StaticMath.o)
gcc -c 文件名.c
注:带参数-c,否则直接编译为可执行文件
然后,通过ar工具将目标文件打包成.a
静态库文件
ar -crv libxxx.a archive files (.o文件)
首先,编写程序:完成主函数、子函数、头文件的编写。
主函数main.c的编写:vim main.c
子函数2头文件sub2.h的编写:vim sub2.h
子函数2头文件sub2.c的编写:vim sub2.c
完成上述文件编写后,在命令行输入
ls
,记录文件情况。
其次,通过gcc生成目标文件.o文件
gcc -c sub1.c sub2.c ···
之后,生成静态库
ar -crv libdoc2.a sub1.o sub2.o
gcc main.c libdoc.a -o sub
【动态库】 在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。
1)动态库把对一些库函数的链接载入推迟到程序运行的时期。
2)可以实现进程之间的资源共享。(因此动态库也称为共享库)
3) 将一些程序升级变得简单。
4) 甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。
gcc -fPIC -shared -o libxxx.so 目标文件(.o)
其中,xxx指动态库的文件,后缀名为".so"。
参数 | 参数含义 |
---|---|
-fPIC | 创建与地址无关的编译程序 |
-shared | 指定生成动态链接库 |
首先,编写源文件;
其次,将一个或几个源文件编译链接,生成共享库;
之后,通过gcc选项链接生成的libxxx.so
;
最后,运行链接了libxxx.so
的程序。
基于上述静态库,利用过程中生成的目标文件.o
文件创建静态库。
第一步,由.o
文件创造动态库
gcc -fPIC -shared -o libmyd oc.so sub1.o sub2.o
1.gcc -o sub main.c -L. -lmydoc
2. ./sub
将动态文件mydoc.so
复制到目录/lib中,输入命令sudo cp libdoc.so /lib
,成功解决!
静态库文件大小:
动态库文件大小:
对比发现,源文件相同,动态库文件比静态库文件要大得多!
通过实际操作深入理解静态库、动态库二者的不同点在于代码被载入的时刻不同。
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在,因此代码体积较小。