linux下静态库和动态库的实现和对比
Posted deshunzhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下静态库和动态库的实现和对比相关的知识,希望对你有一定的参考价值。
首先,创建一个文件夹,并在改文件夹下存进如下文件:
cal.h
#ifndef cal_h #define cal_h int add(int,int); int sub(int,int); int mul(int,int); int div(int,int); int mod(int,int); #endif
add.c
#include"cal.h" int add(int var1, int var2){ return var1 + var2; }
div.c
#include"cal.h" int div(int var1,int var2){ return var1 / var2; }
mod.c
#include"cal.h" int mod(int var1, int var2){ return var1 % var2; }
mul.c
#include"cal.h" int mul(int var1,int var2){ return var1 * var2; }
sub.c
#include"cal.h" int sub(int var1,int var2){ return var1 - var2; }
testcal.c
#include <stdio.h> #include "cal.h" int main(int argc, char **argv) { int var1; int var2; printf("please input var1:"); scanf("%d",&var1); printf("please input var2:"); scanf("%d",&var2); printf("%d add %d is %d ",var1, var2, add(var1,var2)); printf("%d sub %d is %d ",var1, var2, sub(var1,var2)); printf("%d mul %d is %d ",var1, var2, mul(var1,var2)); printf("%d div %d is %d ",var1, var2, div(var1,var2)); printf("%d mod %d is %d ",var1, var2, mod(var1,var2)); return 0; }
一:没有库的实现,首先编写makeflie文件:
OBJ=testcal.o add.o sub.o mul.o div.o mod.o testcal:$(OBJ) cal.h gcc $(OBJ) -o testcal testcal.o:testcal.c add.o:add.c sub.o:sub.c mul.o:mul.c div.o:div.c mod.o:mod.c .PHONY:cleanA clean cleanA: rm testcal $(OBJ) clean: rm $(OBJ)
首先解释一下makeflie文件最重要的第二和第三行代码:testcal表示要生成的目标文件,冒号右边的表示要生成这个文件所要依赖的文件,$(OBJ)表示讲OBJ里的变量取出来。
然后输入make运行,得到以下显示:
cc -c -o testcal.o testcal.c cc -c -o add.o add.c cc -c -o sub.o sub.c cc -c -o mul.o mul.c cc -c -o div.o div.c cc -c -o mod.o mod.c gcc testcal.o add.o sub.o mul.o div.o mod.o -o testcal
同时输入ls -l可以查看文件大小
total 48 -rw-rw-rw- 1 marxism marxism 236 Mar 20 22:17 Makefile -rw-rw-rw- 1 marxism marxism 69 Mar 20 20:52 add.c -rw-rw-rw- 1 marxism marxism 1232 Mar 21 16:55 add.o -rw-rw-rw- 1 marxism marxism 127 Mar 20 20:55 cal.h -rw-rw-rw- 1 marxism marxism 68 Mar 20 20:51 div.c -rw-rw-rw- 1 marxism marxism 1232 Mar 21 16:55 div.o drwxrwxrwx 1 marxism marxism 4096 Mar 21 14:24 libsamp drwxrwxrwx 1 marxism marxism 4096 Mar 21 15:47 libso -rw-rw-rw- 1 marxism marxism 6580 Mar 21 13:57 libzds.a -rw-rw-rw- 1 marxism marxism 68 Mar 20 21:09 mod.c -rw-rw-rw- 1 marxism marxism 1240 Mar 21 16:55 mod.o -rw-rw-rw- 1 marxism marxism 68 Mar 20 20:42 mul.c -rw-rw-rw- 1 marxism marxism 1232 Mar 21 16:55 mul.o -rw-rw-rw- 1 marxism marxism 68 Mar 20 20:40 sub.c -rw-rw-rw- 1 marxism marxism 1232 Mar 21 16:55 sub.o -rwxrwxrwx 1 marxism marxism 8696 Mar 21 16:55 testcal -rw-rw-rw- 1 marxism marxism 496 Mar 20 21:07 testcal.c -rw-rw-rw- 1 marxism marxism 2736 Mar 21 16:55 testcal.o
可以看testcal可执行文件只有9k不到
再运行一下testcal看看结果:
marxism@LAPTOP-8JKP8UGI:~/zds$ ./testcal please input var1:4 please input var2:5 4 add 5 is 9 4 sub 5 is -1 4 mul 5 is 20 4 div 5 is 0 4 mod 5 is 4 marxism@LAPTOP-8JKP8UGI:~/zds$
可见,可以成功编译运行。
二:通过静态库实现
首先要声明一下,在接下来的操作中,我的库文件名称都是zds,首先输入以下代码:
ar rcs libzds.a add.o sub.o mul.o div.o mod.o
在这行代码中,libzds.a里的lib是前缀,zds是你想生成静态库的名字,.a是后缀。
我们可以将这个.a文件和头文件以及可执行文件的.c文件放到一个文件夹中方便操作
然后输入以下代码来生成一个名为testcal的可执行文件:
gcc -o testcal testcal.c -static -L. -lzds
其中,testcal为最终的可执行文件,testcal.c表示要生成testcal所要依靠的文件,这里还要注意以下-L后面是有.的,千万不要漏掉。
输入./testcal
marxism@LAPTOP-8JKP8UGI:~/zds/libsamp$ ./testcal please input var1:2 please input var2:3 2 add 3 is 5 2 sub 3 is -1 2 mul 3 is 6 2 div 3 is 0 2 mod 3 is 2
可见,testcal可以编译运行,在来看看这时的testcal的大小:
-rw-rw-rw- 1 marxism marxism 127 Mar 21 14:01 cal.h -rw-rw-rw- 1 marxism marxism 6580 Mar 21 14:01 libzds.a -rwxrwxrwx 1 marxism marxism 958552 Mar 21 14:24 testcal -rw-rw-rw- 1 marxism marxism 496 Mar 21 14:01 testcal.c
这时testcal的大小有958k,可见比原来的要大了非常多。这就是静态库的一个缺点,个头太大。但是静态库的优点也是有的,比如它适应性很强,是一个以及链接好了的文件。
三:动态库的实现
先创建一个文件夹方便我们操作,再将所有的.o,testcal.c和cal.h放进这个文件夹
首先运行如下命令:
gcc -shared -fPIC -o libzds.so add.o sub.o mul.o div.o mod.o
其中,libzds.so中的lib为前缀,zds为动态库名,.so为动态库后缀。这样就可以生成一个名为zds的动态库
然后输入以下命令:
gcc -o testcal testcal.c -L. -lzds
即可生成一个名为testcal的可执行文件,但当我输入./testcal后却发现无法编译,这时再输入以下指令:
export LD_LIBRARY_PATH=$(pwd)
就可以解决问题了,这是再输入./testcal:
./testcal: error while loading shared libraries: libzds.so: cannot open shared object file: No such file or directory marxism@LAPTOP-8JKP8UGI:~/zds/libso$ export LD_LIBRARY_PATH=$(pwd) marxism@LAPTOP-8JKP8UGI:~/zds/libso$ ./testcal please input var1:4 please input var2:3 4 add 3 is 7 4 sub 3 is 1 4 mul 3 is 12 4 div 3 is 1 4 mod 3 is 1
可见,可以成功运行,再看看文件大小
-rw-rw-rw- 1 marxism marxism 1232 Mar 21 15:07 add.o -rw-rw-rw- 1 marxism marxism 127 Mar 21 15:07 cal.h -rw-rw-rw- 1 marxism marxism 1232 Mar 21 15:07 div.o -rwxrwxrwx 1 marxism marxism 7664 Mar 21 15:45 libzds.so -rw-rw-rw- 1 marxism marxism 1240 Mar 21 15:07 mod.o -rw-rw-rw- 1 marxism marxism 1232 Mar 21 15:07 mul.o -rw-rw-rw- 1 marxism marxism 1232 Mar 21 15:07 sub.o -rwxrwxrwx 1 marxism marxism 8544 Mar 21 17:30 testcal -rw-rw-rw- 1 marxism marxism 496 Mar 21 15:07 testcal.c -rw-rw-rw- 1 marxism marxism 2736 Mar 21 15:43 testcal.o
可以看见,testcal文件只有8k,相比于静态库,动态库生成的可执行文件要小的多,但是动态库的缺点也是有的,例如适应性比较差,容易出现问题。
综上所述,静态库生成的文件适应性强,但是个头太大。动态库生成的文件个头和原来的可执行文件差不多,但是适应性比较差。
在选择这两种库文件时要根据自己的需求来选择。
以上是关于linux下静态库和动态库的实现和对比的主要内容,如果未能解决你的问题,请参考以下文章