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下静态库和动态库的实现和对比的主要内容,如果未能解决你的问题,请参考以下文章

linux下静态库和动态库的制作

Linux下的静态库和动态库

详解Linux下静态库/动态库的生成和使用(含代码示例和操作流程)&&动态库和静态库的区别

关于Linux静态库和动态库的分析

静态库和动态库的区别和win平台和linux平台代码实现

C语言Linux下动态库和静态库详解