【CPP】静态库与动态库

时间:2020-12-17 15:34:04   收藏:0   阅读:39

静态库与动态库

静态库与动态库的比较

函数库本质是一组函数的集合,具有相近的功能或操作。根据链接时期的不同,函数库分为静态库和动态库。

静态库是指链接时,把库文件链接到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。静态库后缀名一般为.a。动态库与之相反,在链接时并没有把库文件链接到可执行文件中,而是仅简单地引用其函数声明,在程序执行时根据需要动态链接库文件,这样可以节省系统的开销。动态库后缀名一般为.so

静态库和动态库的最大区别在于,在静态情况下,把库直接加载到程序中;而动态库链接的时候,它只是保留接口声明,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。

gcc 介绍

Linux 系统下的 gcc 是 GNU 推出的功能强大、性能优越的多平台编译器。gcc 是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高 20%~30%。gcc 编译器能将 C、C++ 语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc 将生成一个名为 a.out 的可执行文件。

静态库是目标文件的一个集合,目标文件中通常仅解析了文件内部的变量和函数,对于引用的函数和变量还没有解析,这需要将其他已经编写好的目标文件引用进来,将没有解析的函数和变量进行解析,通常引用的目标是库。

gcc 编译流程

gcc 编译源代码时,会依次经过预处理-编译-汇编-链接这 4 个流程。

gcc 参数表

参数 含义
-E 只预处理,不编译,生成编译代码.i
-S 只编译,不汇编,生成汇编代码.s
-c 只编译,不链接,生成目标文件.o
-o file 把输出文件输出到 file 里
-v 打印 gcc 的版本
-I dir 在头文件的搜索路径列表中加入 dir 目录
-L dir 在库文件的搜索路径列表中加入 dir 目录
-static 显式链接静态库(静态库也可以用动态库的方式链接)
-lxxx 链接名为 libxxx.so 的动态库

gcc 默认链接动态库。当有静态库与动态库同名时,默认链接动态库,如需指定静态库,需要加-static参数。

静态库

静态库的名字是libxxx.a,其中 xxx 是该 lib 的名称。

生成静态库

在 UNIX 中,使用ar -rc libxxx.a xxx1.o xxx2.o命令创建或者操作静态库。

参数 含义
-r 将目标文件插入静态库尾或者替换静态库中同名文件
-c 创建静态库文件

使用静态库的例子

// add.h
#ifndef _ADD_H
#define _ADD_H
int add(int a, int b);
#endif
// add.cpp
#include "add.h"
int add(int a, int b)
{
    return a + b;
}
// sub.h
#ifndef _SUB_H
#define _SUB_H
int sub(int a, int b);
#endif
// sub.cpp
#include "sub.h"
int sub(int a, int b)
{
    return a-b;
}
// main.cpp
#include "add.h"
#include "sub.h"
#include <iostream>

int main()
{
    std::cout << add(1, 2) << std::endl;
    std::cout << sub(1, 2) << std::endl;
}

动态库

动态库的名字是libxxx.so.major.minor,xxx 是该 lib 的名称,major 是主版本号,minor 是副版本号。版本号也可以没有,一般都会建立个没有版本号的软连接文件链接到全名的库文件。

动态链接库是目标文件的集合,目标文件在动态链接库中的组织方式是按照特殊方式形成的。库中函数和变量的地址是相对地址,不是绝对地址,其真实地址在调用动态库的程序加载时形成。

生成动态库

不同的 Linux 系统,链接动态库方法,实现细节不一样。编译 PIC 型.o中间文件的方法一般是采用 C 语言编译器的-KPIC或者-fPIC选项,有的 Linux 版本 C 语言编译器默认带上了 PIC 标准。创建最终动态库的方法一般采用 C 语言编译器的-G 或者-shared 选项,g++ -fPIC -shared -o libmymath.so add.cpp sub.cpp

参数 含义
-shared 指定生成动态连接库
-fPIC 编译为位置独立的代码,跨平台

使用动态库的例子

源代码同静态库。

库的查找与加载

系统默认的头文件的搜索路径一般为/usr/include, /usr/local/include, /usr/lib/gcc/i486-Linux-gun/4.1.2/include

系统默认的库文件的搜索路径一般为/lib, /usr/lib,具体定义在文件/etc/ld.so.conf或者环境变量LD_LIBRARY_PATH中。

链接时

运行时

由于静态库在链接时已经写入可执行程序,故运行时不需要额外操作了。

但是动态库需要运行时动态地按需调用,与链接时指定的方法不同,运行时则需要系统自行搜索,搜索的路径一般有两种方式指定:

另外还有个文件需要了解/etc/ld.so.cache,里面保存了常用的动态函数库,且会先把他们加载到内存中,因为内存的访问速度远远大于硬盘的访问速度,这样可以提高软件加载动态函数库的速度了。

原文:https://www.cnblogs.com/zghong/p/14149155.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!