静态库和动态库

什么是库

image-20230111151208928

静态库

image-20230111151456815

静态库的制作

image-20230111151601079

eg:

有以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//head.h
int add(int a, int b);
int sub(int a, int b);

//add.cpp
#include<stdio.h>
#include "head.h"
int add(int a, int b)
{
return a+b;
}

//sub.cpp
#include<stdio.h>
#include "head.h"
int sub(int a, int b)
{
return a-b;
}

//main.cpp
#include "head.h"
#include<stdio.h>

int main()
{
printf("%d\n",add(1,2));
printf("%d\n",sub(1,2));
}

使用 g++ -c add.cpp sub.cpp命令编译出add.o, sub.o

image-20230111195506183

使用 ar rcs libcalc.a add.o sub.o命令得到 libcalc.a文件, 即为制作好的静态库

使用静态库

一般来说, 对于一个工程文件, 有include, lib, src目录

include目录装头文件

lib目录装静态库

src目录装源文件

image-20230111202041053

使用 g++ main.cpp -o main -I include/ -l calc -L ./lib/命令编译得到可执行文件main

-I表示指定include目录

-l 表示加入静态库, 名字为calc 注意这个不是静态库文件名, 是库名

-L 表示指定库的目录

动态库

image-20230111204436704

动态库的制作

image-20230112185134664

eg:

同样是上述代码, 使用 g++ -c -fpic add.cpp sub.cpp命令编译出与路径无关的.o文件, 再使用 g++ -c -fpic add.cpp sub.cpp 命令编译出动态库

动态库的使用

首先使用 g++ main.cpp -o main -I include/ -l calc -L lib/命令生成可执行文件, 但是此时的可执行文件不能直接执行,会报错

image-20230112192347193 image-20230112191659625

解决方案: 配置LD_LIBRARY_PATH

(仅在这个终端下生效)

使用export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ergou/桌面/workplace/'Dynamic library'/library/lib命令, 就可以运行main了

关于export命令

export: 用于设置或显示环境变量

1
2
3
4
5
6
7
8
export -p //列出当前的环境变量值export [-fnp][变量名称]=[变量设置值]
-f  代表[变量名称]中为函数名称
-n  删除指定的变量, 变量实际上并未删除, 只是不会输出到后续指令的执行环境中
-p  列出所有的shell赋予程序的环境变量

export -p //列出当前的环境变量值
export MYENV //定义环境变量 MYENV
export MYENV=7 //定义环境变量并赋值

上例中, $LD_LIBRARY_PATH表示获取当前 LD_LIBRARY_PATH 变量的值, 后面的 :balabala就是添加的内容, 大概是一个拼接的作用

(用户级别生效)

cd到home目录, 修改home目录下的.bashrc文件, 在最后一行加入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ergou/桌面/workplace/'Dynamic library'/library/lib命令

保存退出后运行. .bashrcsource .bashrc命令

(系统级别生效)

sudo vim /etc/profile修改这个文件

修改完后source /etc/profile一下

也可以使用 sudo vim /etc/ld.so.conf命令, 将路径添加到里面

保存并退出后使用sudo ldconfig 命令刷新

或者把动态库文件放到 /lib目录或usr/lib目录(不建议, 有把系统原先动态库修改的风险)

静态库与动态库的对比

记得当时面腾讯云智的时候被问了这个问题, 可惜当时的我太菜了连动态库和静态库都不知道…

每日一问: 为什么我这么菜

静态库和动态库的区别来自连接阶段, 如何链接成可执行程序

静态链接:代码从其所在的静态链接库中拷贝到最终的可执行程序中,在该程序被执行时,这些代码会被装入到该进程的虚拟地址空间中。
动态链接:代码被放到动态链接库或共享对象的某个目标文件中,链接程序只是在最终的可执行程序中记录了共享对象的名字等一些信息。在程序执行时,动态链接库的全部内容会被映射到运行时相应进行的虚拟地址的空间。

静态库

优点:发布程序时无需提供静态库,移植方便,运行速度相对快些

缺点:静态链接生成的可执行文件体积较大,消耗内存,如果所使用的静态库发生更新改变,程序必须重新编译,更新麻烦。

动态库

优点:更加节省内存并减少页面交换,动态库改变并不影响使用的程序,动态函数库升级比较方便

缺点:发布程序时需要提供动态库, 慢