Linux 静态库和动态库

在实际开发中,我们把通用的函数和类分文件编写,称之为库。在其它的程序中,可以使用库中的函数和类。
一般来说,通用的函数和类不提供源代码文件(安全性、商业机密),而是编译成二进制文件。
库的二进制文件有两种:静态库和动态库。

1. 静态库

1.1 静态库的概念

程序在编译时会把库文件的二进制代码链接到目标程序中,这种方式称为静态链接。
如果多个程序中用到了同一静态库中的函数或类,就会存在多份拷贝。

1.2 静态库的特点

  • 静态库的链接是在编译时期完成的,执行的时候代码加载速度快。
  • 目标程序的可执行文件比较大,浪费空间。
  • 程序的更新和发布不方便,如果某一个静态库更新了,所有使用它的程序都需要重新编译。

1.3 制作静态库

制作一个简单的静态库:

其中 demo01.cpp代码:

#include "/home/test/tools/public.h"  // 包含通用函数和类的头文件。
using namespace std;

int main()
{
  func();    // 调用通用的函数。

  AA a;      // 用通用类声明对象。
  a.show();  // 调用对象的方法。
}

public.cpp 代码:

// 通用函数和类的代码实现文件。
#include "public.h"
using namespace std;

// 通用函数的代码实现。
void func()
{
  cout << "升级了调用了func()函数。\n";
}

// 通用类的代码实现。
void AA::show()
{
  cout << "我是大帅逼_更新版本。\n";
}

public.h 代码:

// 通用函数和类的头文件。
#include <iostream>

// 声明一个通用的函数。
void func();

// 声明一个通用的类。
class AA
{
public:
  void show();
};

  • 第二步:使用 g++ -o demo01 demo01.cpp /home/test/tools/public.cpp 命令编译 demo01.cpp 和 public.cpp,并运行demo01
    在这里插入图片描述
    这种方法是把 demo01.cpp 和 public.cpp 一起编译,接下来我们把 public.cpp 制作成静态库

  • 第三步:来到 tools文件下
    在这里插入图片描述

g++ -c -o libpublic.a public.cpp

-c 表示 只编译不链接
-o 表示 指定静态库的文件名
静态库文件命名规则 : lib 是前缀, public 是库名, .a表示静态库
最后 public.cpp 是源代码的文件名

可以看到生成了一个新的 libpublic.a 文件
静态库是二进制文件

  • 第四步:使用静态库:命令 g++ -o demo01 demo01.cpp -L/home/test/tools -lpublic

-L 选项表示 指定静态库文件所在的目录
-l 选项表示 需要链接的库名
注意:库名只写 public ,不加 lib 的前缀,也不加.a后缀

在这里插入图片描述可以正常编译,和一起编译两个文件的效果是一样的

2. 动态库

2.1 动态库的概念

程序在编译时不会把库文件的二进制代码链接到目标程序中,而是在运行时候才被载入。
如果多个进程中用到了同一动态库中的函数或类,那么在内存中只有一份,避免了空间浪费问题。

2.2 动态库的特点

  1. 程序在运行的过程中,需要用到动态库的时候才把动态库的二进制代码载入内存。
  2. 程序在运行的过程中,需要用到动态库的时候才把动态库的二进制代码载入内存。
  3. 程序升级比较简单,不需要重新编译程序,只需要更新动态库就行了。

2.3 制作动态库

语法 : == 库名.so 源代码文件清单==

g++ -fPIC -shared -o libpublic.so public.cpp

-fPIC -shared 表示制作动态库
-o 后面跟的是 动态库的文件名 libpublic.so
public.cpp 为源文件

  • 第一步: 进入到tools文件夹,用以上命令制作动态库,为了避免干扰,先把静态库文件删除

在这里插入图片描述

  • 第二步:使用动态库,和静态库方法一致,所以刚才先把静态库的.a文件删除了
g++ -o demo01 demo01.cpp -L/home/test/tools -lpublic

在这里插入图片描述
发现运行不了

这是因为运行可执行程序的时候,需要提前设置 LD_LIBRARY_PATH环境变量。

这个环境变量的作用是 指定动态库文件的目录

echo $LD_LIBRARY_PATH  // 显示环境变量

显示了一堆出来
在这里插入图片描述

  • 接下来我们把动态库的环境变量添加进去即可
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/test/tools

在这里插入图片描述
发现环境变量已经成功添加进去了

  • 第三步,再次运行 demo01
    在这里插入图片描述
    成功运行

动态库优点:

比如说我们后续要更新代码,我们修改之后只需要去重新制作动态库,然后直接运行可执行文件demo01,而不需要重新进行编译,会发现demo01虽然没有重新编译,但是输出效果已经变成更新之后的代码了

这里不做演示了,大家可以自己去尝试一下,步骤:
1.去修改 punlic.cpp 中的cout内容
2.制作动态库 g++ -o demo01 demo01.cpp -L/home/test/tools -lpublic
3.不进行编译,直接执行 demo01

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值