中华视窗是诚信为本,市场在变,我们的诚信永远不变...
静态库与动态库
前言 我们通常把一些公用函数制作成函数库, 供其它程序使用。函数库分为静态库和动态库两种。 静态库在程序编译时会被连接到目标代码中, 程序运行时将不再需要该静态库。 动态库在程序编译时并不会被连接到目标代码中, 而是在程序运行是才被载入, 因此在程序运行时还需要动态库存在。 一、编写函数
#ifndef _SUB1_H
#define _SUB1_H
float x2x(int a, int b);
#endif
#include
#include "sub1.h"
float x2x(int a, int b)
{
return (float)(a+b);
}
#ifndef SUB2_H
#define SUB2_H
void x2y();
#endif
#include
void x2y()
{
printf("Please input two number\n");
}
#include
#include "sub1.h"
#include "sub2.h"
int main()
{
int x ,y;
float sum;
x2y();
scanf("%d %d",&x,&y);
sum=x2x(x,y);
printf("%0.2f\n",sum);
}
二、生成静态库
无论静态库, 还是动态库, 都是由.o 文件创建的。 因此, 我们必须将源程序 hello.c 通过 gcc 先编译成.o 文件。静态库文件名的命名规范是以 lib 为前缀, 紧接着跟静态库名, 扩展名为.a,如.a。
gcc -c sub1.c
gcc -c sub2. c
ar -crv .a sub1.o sub2.o
gcc main.c .a -o test
rm .a
继续执行./test,程序能正常工作 ,说明确实在链接过程中静态库已被连接到目标代码中去。
静态链接库(.a)文件其实就是将多个文件(.o)文件打包成一份文件。链接过程可以使用.a或者.o文件。
ar -t libtest.a
其实我们之前使用静态库链接文件,就是将打包的.o文件编译
gcc main.c libtest.a -o test
gcc main.c sub1.o sub2.o -o test
经过测试,使用此命令效果与静态库一样
三、生成动态库
动态库文件名的命名规范是以 lib 为前缀, 紧接着跟动态库名(用户自定义), 扩展名为.so,如.so。
gcc -shared -fPIC -o libtest.so sub1.o sub2.o
gcc main.c libtest.so -o test1
./test1
但是这是怎么回事呢?为什么提示说找不到文件或目录呢?
原来是我们刚才创建的动态库文件未被找到
库文件在连接(静态库和共享 库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。
sudo mv libtest.so /usr/lib
正时由于程序在执行时需要动态库,所以当系统在默认路径找不到对应的动态库,即会出错。
四、对比分析
静态库
当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被 copy到最终的可执行文件中。这就会导致最终生成的可执行代码量相对变多,相当于编译器将代码补充完整了。
优点,这样运行起来相对就快些。
缺点:占用磁盘和内存空间. 静态库会被添加到和它连接的每个程序中, 而且这些程序运行时, 都会被加载到内存中. 无形中又多消耗了更多的内存空间。
动态库
与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时, 那些需要的函数代码才被拷贝到内存中。优点,这样就使可执行文件比较小, 节省磁盘空间,更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用,也同时节约了内存。
缺点,不过由于运行时要去链接库会花费一定的时间,执行速度相对会慢一些,总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率,没有好与坏的区别,只看具体需要了。
另外,一个程序编好后,有时需要做一些修改和优化,如果我们要修改的刚好是库函数的话,在接口不变的前提下,使用共享库的程序只需要将共享库重新编译就可以了,而使用静态库的程序则需要将静态库重新编译好后,将程序再重新编译一便。这也是使用过程当中的差别,以现在的项目举例,在远程更新的时候,如果只是*.so动态库封装内容变化了,那么只需要更新*.so即可。
动态库与静态库优缺点比较
总结
一般来说,动态库生成的可执行文件比静态库生成的文件小,但是在用size命令查看生成文件大小时,却发现动态库生成的可执行文件更大(有可能是我操作不当),百思不得其解?如果有朋友知道,欢迎留言,不胜感激!!!