日期:2014-05-16  浏览次数:20641 次

Linux下静态库和动态库的区别

首先看看静态库和动态库的定义

linux下的库有两种:静态库和共享库(动态库)。
二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。
不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

下面通过一个实例来说明一下静态库和动态库的区别。
构建程序,最简单的hellworld,其目录结构如下:
test
???? --hello.h
???? --hello.c
???? --test.c

?

各文件代码如下:

hello.h

void hello(void); 

?

hello.c

#include "hello.h"
void hello(void) 
 { 
     printf("Hello World\n");
 }

?

test.c

#include "hello.h" 

int main(void) 
{ 
   hello(); 
   return 0; 
}

??

下面我们就分别做成静态库和动态库。

1. 静态库的制作
# gcc -o hello.o -c hello.c?? //编译
# ar cqs libhello.a hello.o?? //本步骤生成静态库
经过上述的步骤后,将会生成libhello.a的静态库。

?

下面编译test.c文件。
# gcc test.c libhello.a -o test

?

经过编译后,生成名为test的可执行文件,下面我们用ldd命令来看一下它的引用情况。
# ldd test
??????? libc.so.6 => /lib64/libc.so.6 (0x00000032a0e00000)
??????? /lib64/ld-linux-x86-64.so.2 (0x00000032a0a00000)

?

2. 动态库的制作
# gcc -fPIC? -o hello.o -c hello.c
# gcc -shared -Wall -fPIC -o libhello.so hello.o?? //本步骤生成动态库
经过上述的步骤后,将会生成libhello.so的静态库。将libhello.so拷贝到/usr/lib/目录下。
# cp libhello.so /usr/lib/

?

下面编译test.c文件。
# gcc test.c -lhello -o test1

?

经过编译后,生成名为test1的可执行文件,下面我们用ldd命令来看一下它的引用情况。
# ldd test1
??????? libhello.so (0x00002b67c9237000)
??????? libc.so.6 => /lib64/libc.so.6 (0x00000032a0e00000)
??????? /lib64/ld-linux-x86-64.so.2 (0x00000032a0a00000)

?

看到区别了吧,是不是比静态链接的程序多了一个 libhello.so ?
这就是静态与动态的最大区别,静态情况下,他把库直接加载到程序里。

而在动态链接的时候,他只是保留接口,将动态库与程序代码独立。这样就可以提高代码的可复用度,和降低程序的耦合度。

?

?

?