1.什么是静态库
静态库是指在应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。
1.1命名方式:
静态库的文件名命名方式是“libxxx.a”,库名前面加“lib”,windows和linux下后缀都用的是“.a”,“xxx”为静态库名。
1.2链接时间:
编译过程中被载入程序
1.3连接方式:
静态库的链接是将整个函数库的所有数据都整合进了目标代码。
1.4 优缺点:
·优点:这样做的一个优点就是可执行程序可以直接运行,不再需要外部函数库的支持,因为所有函数都已经被编进去了。运行效率较高。
·缺点:假如多个程序使用同一个静态库,等同于多段相同的代码分别保存在不同的可执行程序中,变相占用了更多的内存空间。而且如果所使用的静态库发生更新改变,你的程序必须重新编译。
2.什么是动态库
动态库就是编译程序时,可执行程序中只保存对应的函数的引用表,只有到程序执行时,再链接对应的库。
2.1命名方式:
动态库的命名方式与静态库类似,前缀相同为“lib”,linux下后缀名为“.so(shared object)”即libxxx.so;而windows 下后缀名为“.dll(dynamic link library)”即libxxx.dll.
2.2链接时间和方式:
动态库在编译的时候并没有被编译进目标代码,而是当你的程序执行到相关函数时才调用该函数库里的相应函数。
2.3 优缺点:
·优点:多个可执行程序共用同一个库,节省内存。且动态库的改变并不影响 你的程序,所以动态函数库升级比较方便。
·缺点:因为函数库并没有整合进程序,所以程序的运行环境必须提供相应的库,运行可执行程序需要额外做一次链接操作,执行速度会相对慢一些。
3.使用方法
- -o: 指定编译生成可执行文件名
- -I:指定头文件的路径(这里是大写i)
- -l:指定所需链接库的库名(这里是L的小写)
- -L:指定链接所需要的库所在的路径
- -static:静态链接
程序演示:
main.c
13 #include<stdio.h>
14 #include "test.h"
15 int main(int argc ,char **argv)
16 {
17 printf("sum = %d\n",sum(4,6));
18 printf("avg= %d\n",avg(4,6));
19 return 0;
20 }
sum.c
int sum (int a,int b)
{
return a+b;
}
avg.c
int avg(int a,int b)
{
return (a+b)/2;
}
test.h
#ifndef _TEST_H_
#define _TEST_H_
extern int sum(int a,int b);
extern int avg(int a,int b);
#endif
3.1制作静态库
gcc -c avg.c sum.c
ar -crs libstatic.a avg.o sum.o
3.2制作动态库
gcc -fpic -shared sum.c avg.c -o libshared.so
运行时往往会出现这样的报错 ,那么这是为什么呢?
原因是:Linux下在运行程序时,会默认到 /lib、/lib64、/usr/lib以LD_LIBRARY_PATH环境变量指定的路径下查找所需的动态库下查找所需的动态库文件,如果没有则抛错。而这时libshared.so并不在系统库路径下,所以会出错。我总结了以下四种解决方法:
(1)将所需要的libshared.so文件拷贝到/usr/lib路径下,当然这需要root权限。
(2)使用export命令在LD_LIBRARY_PATH环境变量中添加该动态库所在的路径,注意该命令只是临时生效,环境变量都是临时生效的,重启后失效。另外指定的路径必须是绝对路径;(用pwd命令查看绝对命令)。
(3) 可以用vim ~/.bashrc将路径加进shell配置文件里 source ~/.bashrc 生效命令或者重启都可以。因为每次启动用户账号,该用户的shell配置文件都会重新运行一次,所以使用该方法不用每次都设置。
(3) 在编译时添加 -Wl,-rpath,/your/lib/path/ (-Wl,-R /your/lib/path/)
在gcc中使用ld链接选项时,需要在选项前面加上前缀-Wl(小写L), -R(或-rpath)指定程序运行时库的路径。注意: 这个方法优点是不需要更改环境变量或者拷贝动态库到系统路径下, 它的缺点是只要更改了动态库, 那么就需要重新编译(就这一点而言类似于静态库)。
//对于本例子:
gcc main.c -o test -Wl,-R(运行时库的路径) -lshared -L库的路径 -I头文件路径
4.二者的区别总结
前面对于静态库动态库的介绍已经说明了两者的区别,在此归纳为以下三点:
生成可执行文件大小、可执行文件执行速度、库生效方式。
总结而言:静态库牺牲了空间效率,换取了时间效率;动态库牺牲了时间效率,换取了空间效率。没有好坏区别,只看具体需要。