静态库与动态库

什么是库?
库从本质上来讲是一种可执行代码的二进制格式,可以被载入到内存中去执行。库可分为静态库动态库两种,二者之间的区别在于代码被在不的时刻不同

静态库:这类库的名字一般是libxxx.a,xxx为库的名字,静态库在程序编译时会被链接到目标代码中,由于整个函数库的所有数据都会被整合到目标代码中,故此静态函数库编译成的文件会比较大。显然它的优点在于编译执行后不需要函数库的支持,整个函数库在编译期间都已经被加载到目标代码中。但是当函数库发生改变时,它也需要重新编译
动态库:这类库的名字一般是libxxx.M.N.so,M是库的主版本号,N是库的副版本号,当然版本号也可以不需要。相较于静态库而言,动态库在编译期间并没有被加载到目标代码中,程序只有在执行到相关函数是才会到函数库中去调用,所以动态库产生的可执行文件比较小。由于函数库并没有被整合到程序中,而是程序在运行时动态申请调用,所以程序的运行环境必须提供相应的库。动态库的更新并不会影响程序的执行,所以动态库函数的升级比较方便

当要使用静态的函数库时,连接器会找到程序所需要的函数,然后将他们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态库就不需要了。然而,对于动态库而言,就不是这样,动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是先连接动态库。

静态库
-.生成静态库
(1)我们假定现在有静态库st1,st2制作库libmytest.a.如下

[root@localhost Testlib]# cat str1.c
#include<stdio.h>

void print1()
{
    printf("i am print1\n");
}
[root@localhost Testlib]# cat str2.c
#include<stdio.h>

void print2()
{
    printf("i am print2\n");
}
[root@localhost Testlib]# cat main.c
#include<stdio.h>

int main( int argc, const char* argv[] )
{
    print1();
    print2();

    return 0;
}

(2)生成libmytest.a文件
生成libmytest.a,它将很多.o生成.a

[root@localhost Testlib]# gcc -c str1.c str2.c
[root@localhost Testlib]# ar crs libmytest.a str1.o str2.o
[root@localhost Testlib]# ls
libmytest.a  main.c  str1.c  str1.o  str2.c  str2.o
[root@localhost Testlib]# file libmytest.a 
libmytest.a: current ar archive

(3)使用静态库

[root@localhost Testlib]# gcc -o test main.c -L. -lmytest
[root@localhost Testlib]# ./test
i am print1
i am print2

gcc的参数-L是告诉编译器库文件是当前目录,-l是告诉编译器要使用的库的名字是mytest

动态库
动态库的基本概念:
1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序。动态链接库是目标文件的集合,目标文件在动态连接库中的组织方式是按照特殊方式形成的。库中函数和变量的地址是相对地址,不是绝对地址,其真实地址在调用动态库的程序加载时形成。
2、动态链接库的名称有别名(soname), 真名(realname)和链接名(linker name)。别名由一个前缀lib,然后是库的名字,再加上一个后缀“.so”构成(“libxxx.so”)。真名是动态链接库真实名称,一般总是在别名的基础加上一个小版本号,发布版本等构成。除此之外,还有一个链接名,即程序链接时使用的库的名字。
3、在动态链接库安装的时候,总是复制文件到某个目录下,然后用一个软连接生成别名,在库文件进行更新的时候,仅仅更新软链接即可。

生成动态库

[root@localhost dylib]# cat main.c
#include "mylib.h"

int main( int argc, const char* argv[] )
{
    print1();
    print2();
    return 0;
}
[root@localhost dylib]# cat mylib.h
#ifndef  __MYLIB_H__
#define  __MYLIB_H__

#include<stdio.h>

void print1();
void print2();

#endif  //__MYLIB_H__
[root@localhost dylib]# cat dy1.c
#include "mylib.h"

void print1()
{
    printf("my first lib\n");
}
[root@localhost dylib]# cat dy2.c
#include "mylib.h"

void print2()
{
    printf("my second lib\n");
}

将dy1.c和dy2.c用来创建动态库

[root@localhost dylib]# gcc -o libmytest.so -fPIC -shared dy1.c dy2.c

-fPIC指定生成与地址无关的编译程序,-shared指定生成动态链接库
使用动态库
在使用动态库前我们需要将其放入/lib中,因为在运行中程序链接的动态链接库需要在系统目录下。

[root@localhost dylib]# cp libmytest.so /lib
[root@localhost dylib]# gcc -o test main.c -L. -lmytest
[root@localhost dylib]# ./test
my first lib
my second lib

当然也可以不用拷贝
在 LD_LIBRARY_PATH 环境变量中加上库所在路径

[root@localhost dylib]# export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH 

猜你喜欢

转载自blog.csdn.net/nuyexiaoxiang/article/details/79500645
今日推荐