一、静态库和动态库
静态库是指程序在编译阶段就把库文件嵌入到程序中的三方库,这种行为在程序运行前就已经决定了,程序在编译完成后不再依赖库文件。
动态库和静态库不一样,它是在程序运行期间才发生的调用行为,不会嵌入到程序,相对来说,链接动态库的二进制文件体积更小。
windows和linux平台下的静态/动态库后缀分别为lib dll和.a .so,其中linux中动态库的命名规则为:libxxx.so.x.y.z,xxx表示库名,x是主版本号,y是此版本号,z是发行版本号。
二、静态库的使用
创建一个三方库的源文件func1.c:
#include
int add(int x, int y) {
return x + y;
}
int sum(int cnt, ...) {
int sum = 0;
va_list ap;
va_start(ap, cnt);
while(cnt--)
sum += va_arg(ap, int);
va_end(ap);
return sum;
}
#include
intadd(intx,inty){
returnx+y;
}
intsum(intcnt,...){
intsum=0;
va_listap;
va_start(ap,cnt);
while(cnt--)
sum+=va_arg(ap,int);
va_end(ap);
returnsum;
}
生成目标文件:
> gcc -c func1.c # 此时会生成.o文件
> ls
func1.c func1.o
>gcc-cfunc1.c# 此时会生成.o文件
>ls
func1.cfunc1.o
将目标文件生成库文件:
> ar cr libfunc1.a func1.o # 文件名一定要是libxxx.a
> ls # 此时会生成静态库文件
func1.c func1.o libfunc1.a
>arcrlibfunc1.afunc1.o# 文件名一定要是libxxx.a
>ls# 此时会生成静态库文件
func1.cfunc1.olibfunc1.a
编写主文件main.c:
#include
// 声明库中的函数,也可以写在头文件中包含。
int add(int, int);
int sum(int, ...);
int main() {
printf("%d\n", add(1, 2));
printf("%d\n", sum(5, 1, 2, 3, 4, 5));
return 0;
}
#include
// 声明库中的函数,也可以写在头文件中包含。
intadd(int,int);
intsum(int,...);
intmain(){
printf("%d\n",add(1,2));
printf("%d\n",sum(5,1,2,3,4,5));
return0;
}
编译主程序:
gcc main.c -L. -lfunc1 -o app
1
gccmain.c-L.-lfunc1-oapp
-l选项后面加库名表示要链接的库,系统默认在系统的库文件目录(/lib, /usr/lib, /usr/local/lib)中查找,如果库文件不在这几个目录中,则要通过-L文件指定目录。
编译好后运行(删除libfunc1.a文件程序依旧可以运行):
> ./app
3
15
>./app
3
15
三、动态库的使用
依旧使用上面的func1.c文件,编译动态库:
> gcc -fPIC -c -o func1.o func1.c # 生成.o文件
> gcc -shared -o libfunc1.so func1.o # 生成动态库
>gcc-fPIC-c-ofunc1.ofunc1.c# 生成.o文件
>gcc-shared-olibfunc1.sofunc1.o# 生成动态库
上述步骤也可以缩成一步:
> gcc func1.c -fPIC -shared -o libfunc1.so
1
>gccfunc1.c-fPIC-shared-olibfunc1.so
执行完后将会生成一个libfunc1.so:
> ls
ma@ubuntu:/code/code/Makefile$ ls
func1.c func1.o libfunc1.so main.c
1
2
3
>ls
ma@ubuntu:/code/code/Makefile$ls
func1.cfunc1.olibfunc1.somain.c
编译主程序:
> gcc main.c -lfunc1 -o app
/usr/bin/ld: cannot find -lfunc1
collect2: error: ld returned 1 exit status
>gccmain.c-lfunc1-oapp
/usr/bin/ld:cannotfind-lfunc1
collect2:error:ldreturned1exitstatus
执行会报错,找不到库func1,添加上-L选项:
> gcc main.c -lfunc1 -o app -L. # 成功编译
> ./app # 运行出错
./app: error while loading shared libraries: libfunc1.so: cannot open shared object file: No such file or directory
>gccmain.c-lfunc1-oapp-L.# 成功编译
>./app# 运行出错
./app:errorwhileloadingsharedlibraries:libfunc1.so:cannotopensharedobjectfile:Nosuchfileordirectory
加上-L选项后能完成编译,但是运行时还是找不到动态库,此时的解决方法可以查看:'xxx': error while loading shared libraries的解决方案,解决依赖后运行程序: