比较早出现的是静态链接库。静态库其实就是商业公司将自己的函数库源代码经过只编译不连接形成.o的目标文件,然后用ar工具将.o文件归档成.a的归档文件(.a的归档文件又叫静态链接库文件)。商业公司通过发布.a库文件和.h头文件来提供静态库给客户使用;客户拿到.a和.h文件后,通过.h头文件得知库中的库函数的原型,然后在自己的.c文件中直接调用这些库文件,在连接的时候链接器会去.a文件中拿出被调用的那个函数的编译后的.o二进制代码段链接进去形成最终的可执行程序。
2:动态链接库
动态链接库比静态链接库出现的晚一些,效率更高一些,是改进型的。现在我们一般都是使用动态库。静态库在用户链接自己的可执行程序时就已经把调用的库中的函数的代码段链接进最终可执行程序中了,这样好处是可以执行,坏处是太占地方了。尤其是有多个应用程序都使用了这个库函数时,实际上在多个应用程序最后生成的可执行程序中都各自有一份这个库函数的代码段。当这些应用程序同时在内存中运行时,实际上在内存中有多个这个库函数的代码段,这完全重复了。而动态链接库本身不将库函数的代码段链接入可执行程序,只是做个标记。然后当应用程序在内存中执行时,运行时环境发现它调用了一个动态库中的库函数时,会去加载这个动态库到内存中,然后以后不管有多少个应用程序去调用这个库中的函数都会跳转到第一次加载的地方去执行(不会重复加载)
3:静态链接库和动态链接库的比较
静态库是用户在链接字节的可执行程序时已经将调用到的库函数的代码段链接到最终的可执行程序中,这样的好处是这样的可执行文件放到任何地方都能执行,坏处是库函数很占地方,使得链接得到的最终的可执行程序变得很大。
使用动态库的时候,函数本身编译链接到得到可执行程序的时候,并不会讲库函数链接到可执行程序中去,而是标记这个函数用到哪些库函数,当这个可执行程序运行时,操作系统会自动加载这些库到内存中。
比较:
通过上面的分析可以知道,静态库是将库函数链接到最终的可执行程序中,而动态库是没有将库函数链接到可执行程序中。从单个可执行程序的角度出发可执行程序在内存中运行时,系统还是会将库函数加载到内存中,这样从内存角度上讲,两个可执行程序最终在内存中运行时所占的空间还是一样的。但是从多个程序出发,就不一样了,比如a程序和b程序都用到了printf函数,使用静态库时,这两个可执行程序都包含了printf函数,所以这时候内存中就包含了两份printf函数;而使用动态库的时候,系统只会加载一份printf函数,当其他函数也要用到printf函数时,只要到加载的printf函数的地址中调用即可,不需要再次加载,所以当多个程序运行时,静态库就明显比动态库更占内存。
4:函数库中库函数的使用
(1)gcc中编译链接程序默认是使用动态库的,要想静态链接需要显式用-static来强制静态链接。
(2)库函数的使用需要注意3点:第一,包含相应的头文件;第二,调用库函数时注意函数原型;第三,有些库函数链接时需要额外用-lxxx来指定链接;第四,如果是动态库,要注意-L指定动态库的地址。