在 windows 平台和 linux 平台下都大量存在着库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于 windows 和 linux 的本质不同,因此二者库的二进制是不兼容的。通俗的说就是把这些常用函数的目标文件打包在一起,提供相应函数的接口,便于程序员使用。在使用函数时,只需要包对应的头文件即可。按照库的使用方式又可分为动态库和静态库,在不同平台下对应后缀也有所不同。
WINDOWS 下:.dll 后缀为动态库,.lib 后缀为静态库;
LINUX 下:.so 后缀为动态库,.a 后缀为静态库。
<1> 静态库:
静态库可以简单的看成一组目标文件的集合,即很多目标文件经过压缩打包后形成的文件。比如在我们日常编程中,如果需要使用 printf 函数,就需要包 stdio.h 的库文件,使用 strlen 时,又需要包 string.h 的库文件,可是如果直接把对应函数源码编译后形成的. o 文件直接提供给我们,将会对我们的管理和使用上造成极大不便,于是可以使用 "ar" 压缩程序将这些目标文件压缩在一起,形成 libx.a 静态库文件。
注:静态库命名格式:lib + "库名称"+ .a(后缀) 例:libadd.a 就是一个叫 add 的静态库
<2> 静态链接:
对于静态库,程序在编译链接时,将库的代码链接到可执行文件中,程序运行时不再需要静态库。在使用过程中只需要将库和我们的程序编译后的文件链接在一起就可形成一个可执行文件。
注:详细关于静态库及静态链接可参考《程序员的自我修养——链接、装载与库》第四章
/////main.c/////
#include
#include "add.h"
int main()
{
int ret = add(3, 4);
printf("3 + 4 = %d\n",ret);
return 0;
}
/////add.c/////
#include "add.h"
int add( int x, int y)
{
return x + y;
}
/////add.h/////
#pragma once
#include
int add( int x, int y);
/////Makefile/////
main : main.c libadd.a
gcc main.c -L . -ladd -o main
//-L为指定路径 .为当前目录下 -l+库名字,编译器可在指定目录下自己寻找名为add的库文件
libadd.a :
gcc -c add.c -o add.o
//ar -rc将多个编译后的文件打包为一个静态库文件
ar -rc libadd.a add.o
.PHONY:clean
clean:
rm main libadd.a
<3> 缺点:
1、内存和磁盘空间浪费:静态链接方式对于计算机内存和磁盘的空间浪费十分严重。假如一个 c 语言的静态库大小为 1MB,系统中有 100 个需要使用到该库文件,采用静态链接的话,就要浪费进 100M 的内存,若数量再大,那浪费的也就更多。例如下图:程序 1 和程序 2 都需要用到 Lib.o,采用静态链接的话,那么物理内存中就会存放两份对应此文件的拷贝。
2、更新麻烦:比如一个程序 20 个模块,每个模块只有 1MB,那么每次更新任何一个模块,用户都得重新下载 20M 的程序。
<1> 动态库:程序在运行时才去链接动态库的代码,多个程序共享库的代码。一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
注:动态库命名格式:lib + "库名称"+ .so(后缀) 例:libadd.so 就是一个叫 add 的动态库
<2> 动态链接:由于静态链接具有浪费内存和模块更新困难等问题,提出了动态链接。基本实现思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将他们链接在一起形成一个完整的程序,而不是像静态链接那样把所有的程序模块都链接成一个单独的可执行文件。所以动态链接是将链接过程推迟到了运行时才进行。
/////Makefile/////
main : main.c libadd.so
gcc main.c -L . -ladd -o main
libadd.so :
gcc -fPIC -shared add.c -o libadd.so
//-shared表示输出结果是共享库类型的 -fPIC表示使用地址无关代码奇数来生产输出文件
.PHONY:clean
clean:
rm main libadd.so
<3> 优点:①毋庸置疑的就是节省内存;②减少物理页面的换入换出;③在升级某个模块时,理论上只需要将对应旧的目标文件覆盖掉即可。新版本的目标文件会被自动装载到内存中并且链接起来;④程序在运行时可以动态的选择加载各种程序模块,实现程序的扩展。
图片截图来自《程序员的自我修养——链接、装载与库》
来源: http://blog.csdn.net/sssssuuuuu666/article/details/78788369