一、什么是程序库
通俗的讲,一个程序库就是目标程序文件的一个集合。如果某些目标文件提供了解决一个特定问题的所需功能,我们就可以把这些目标文件归并为一个程序库,从而让应用开发者更易于访问这些目标文件,省得到处去找。
对于静态库,我们可以用实用程序ar来建立。当应用程序开发人员利用程序库进行程序的编译和连接时,程序库中为应用程序所需的那些元件就会集成到最终生成的的可执行程序中。之后,因为程序库已经融入应用程序的映像之中,成为它密不可分的一部分了,所以对应用程序来说,已经没什么外部的程序库可言了。
共享程序库(或者动态程序库)也会连接到一个应用程序的映像上,不过需要两个不同的步骤。第一步发生在构建应用程序之时,链接程序检查是否在应用程序或者程序库内部找到了构建应用程序所需的全部符号(函数名或变量名)。第二步发生在运行时,动态加载器把所需的共享库载入内存,然后动态地把它链接到应用程序的映像之中。注意,这里与静态程序库不同,这次并没有把共享程序库中的所需元件放入应用程序的映像之中。很明显,这样生成的应用程序映像较小,因为共享程序库和应用程序的映像是相互独立的,如下图所示。

图1 静态库示意图
图2 动态库示意图
虽然共享库能够节约内存,但是这是有代价的——必须在运行时解析程序库。很明显,要想弄清需要哪些库,然后寻找这些库并将其载入内存肯定是需要一定时间的。
本文中,我们会建立两个程序库,一个静态库和一个动态库,并以各自的方式应用于程序之中,以此亲身体验两者之间的区别。
二、静态库的创建和使用
相对于动态链接库,静态库要简单一些,它被静态的链接到应用程序的映像之中。这意味着,映像一旦建好,外部程序库的有无对映像的执行将毫无影响,因为所需的部分已经放进程序二进制映像了。
下面我们来演示如何用一组源文件来构造一个程序库。我们建立的程序库是用来封装GNU/Linux的随机函数的,这样我们的库就可以对外提供随机数生成器了。现在看一下我们的程序库为应用程序提供的接口(API),我们将其放在头文件randapi.h中,如下所示:
| //randapi.h,我们的程序库的接口
#ifndef __RAND_API_H
#define __RAND_API_H
extern void initRand( void );
extern float getSRand( void );
extern int getRand( int max );
#endif /* __RAND_API_H */ |