【Linux 相关】 静态库与动态库的编译和使用

参考博客 http://www.cnblogs.com/feisky/archive/2010/03/09/1681996.html

上述博客中关于静态库与动态库的讲解,很清晰!

库的定义:

库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 

静态库和动态库的区别

1. 静态函数库

    这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

2. 动态函数库

    这类库的名字一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。 
linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。

示例:

静态库的编译与使用:

 1 //***static_lib1.c***
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 
 6 int printSelf1()
 7 {
 8     printf("I am static lib 1\n");
 9     return 0;
10 }

 

 1 //***static_lib2.c***
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 
 6 int printSelf2()
 7 {
 8     printf("I am static lib 2\n");
 9     return 0;
10 }
 1 //***main.c***
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 
 6 int main()
 7 {
 8     printSelf1();
 9     printSelf2();
10     return 0;
11 }

 

 

 

#***makefile***
main:main.c static_lib
    gcc main.c -L. -lstatic_lib -o main
#***just compile c file
static_lib1:static_lib1.c
    gcc -c static_lib1.c
#***just compile c file
static_lib2:static_lib2.c
    gcc -c static_lib2.c
#***create statlic lib***
static_lib:static_lib1.o static_lib2.o
    ar -rsv libstatic_lib.a static_lib1.o static_lib2.o
    rm -rf static_lib1.o static_lib2.o
clean:
    rm -rf main
    rm -rf libstatic_lib.a

 

执行步骤:

[xbh@bogon static_lib]$ make
cc    -c -o static_lib1.o static_lib1.c
cc    -c -o static_lib2.o static_lib2.c
ar -rsv libstatic_lib.a static_lib1.o static_lib2.o
r - static_lib1.o
r - static_lib2.o
rm -rf static_lib1.o static_lib2.o
gcc main.c -L. -lstatic_lib -o main
[xbh@bogon static_lib]$ ar -t libstatic_lib.a 
static_lib1.o
static_lib2.o
[xbh@bogon static_lib]$ ./main 
I am static lib 1
I am static lib 2

 

注: ar 命令与静态库相关,用于出库已经查询库信息

动态库的编译与使用:

 1 //***dynamic.c***
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 
 6 int printSelf()
 7 {
 8     printf("this is a dynamic lib src\n");
 9     return 0;
10 }
 1 //***main.c***
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 
 6 int main()
 7 {
 8     printSelf();
 9     return 0;
10 }

 

#***makefile***
main:main.c dynamic_lib
    gcc main.c -L. -ldynamic_lib -o main 
#***create dynamic lib libdynamic_lib.so
dynamic_lib:dynamic.c
    gcc -fPIC -shared dynamic.c -o libdynamic_lib.so
clean:
    rm -rf main

 

编译成功后执行步骤如下:

[xbh@bogon dynamic_lib]$ ./main
./main: error while loading shared libraries: libdynamic_lib.so: cannot open shared object file: No such file or directory
[xbh@bogon dynamic_lib]$ export LD_LIBRARY_PATH=.
[xbh@bogon dynamic_lib]$ csh
[xbh@bogon dynamic_lib]$ setenv LD_LIBRARY_PATH .
[xbh@bogon dynamic_lib]$ ldd -r main
	linux-gate.so.1 =>  (0x00b9b000)
	libdynamic_lib.so => ./libdynamic_lib.so (0x0084a000)
	libc.so.6 => /lib/libc.so.6 (0x008dd000)
	/lib/ld-linux.so.2 (0x008bf000)
[xbh@bogon dynamic_lib]$ ./main
this is a dynamic lib src

 

注:直接执行会报错,因为没有定义LD_LIBRARY_PATH环境变量时,动态库的查找路径只是/usr/lib, /lib; 只有设置了环境变量才可以找到动态库;

使用ldd -r main 就是检查库的依赖关系

其中csh命令是切换用户的shell为cshell, 用户登录默认shell为bash,这里做切换只是为了演示在csh,bash下分别如何设置环境变量。

 

对于在代码中动态调用动态库的方式这里就不记录了,可以参考文章开头中的博客,觉得写得挺好

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。