静态库和动态库制作


前言

我们在编写代码的时候经常用到已有的接口,他们是以库的形式提供给我们使用的,而常见形式有两种,一种常以 .a 为后缀,为静态库;另一种以 .so 为后缀,为动态库。所谓的静态、动态指的是链接的过程。


一、静态库和动态库介绍

1、静态库

程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再需要静态库。

静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存,100M 展开 100 次,就是 10G,但是这样的好处就是静态加载的速度快。
在这里插入图片描述

2、动态库

程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

使用动态库会将动态库加载到内存,10 个文件也只需要加载一次,然后这些文件用到库的时候临时去加载,速度慢一些,但是很省内存。
在这里插入图片描述

二、静态库的制作及使用

静态库的名字是以 lib 开头,以 .a 结尾,例:libmylib.a

静态库生成的指令:

ar rcs libmylib.a file1.o

1、准备好源码

test.c

#include <stdio.h>
#include "sub.h"

int main(int argc, char *argv[])
{
    int i = 6, j = 3;
    int k;

    printf("main fun! && i = %d\n", i);
    k = sub_fun(i, j);
    printf("k = %d\n", k);

    return 0;
}

sub.c

#include <stdio.h>

int sub_fun(int a, int b)
{
    printf("sub fun!\n");
    return a - b;
}

sub.h

int sub_fun(int, int);

2、编译源码生成 .o 文件

gcc -c sub.c -o sub.o

在这里插入图片描述

3、制作静态库

ar rcs libmymath.a sub.o

在这里插入图片描述

4、使用静态库

gcc test.c libmymath.a -o test
./test

在这里插入图片描述
test.c 文件仅有 213 字节,而 test 文件有 16K 大小,所以静态库使用时,是直接编译到文件里面的。
在这里插入图片描述

三、动态库的制作及使用

动态库的名字是以 lib 开头,以 .so 结尾,例:libmylib.so

1、生成位置无关的 .o 文件

gcc -c sub.c -o sub.o -fPIC

在这里插入图片描述
使用 -fPIC 这个参数过后,生成的函数就和位置无关,挂上 @plt 标识,等待动态绑定

2、制作动态库

gcc -shared -o libmymath.so sub.o

在这里插入图片描述

3、使用动态库

  • -l :指定库名
  • -L :指定库路径
gcc test.c -o test -l mymath -L ./
./test

在这里插入图片描述
出错原因分析:

  • 连接器: 工作于链接阶段,工作时需要 -l 和 -L
  • 动态链接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置

解决办法:指定动态库路径并使其生效,然后再执行文件

4、指定动态库路径并使其生效

通过环境变量指定动态库所在位置: export LD_LIBRARY_PATH=动态库路径

export LD_LIBRARY_PATH=./
./test

在这里插入图片描述
当关闭终端,再次执行 test 时,又报错。
在这里插入图片描述
这是因为,环境变量是进程的概念,关闭终端之后再打开,是两个进程,环境变量发生了变化。
要想永久生效,需要修改 bash 的配置文件: vi ~./bashrc

永久生效方法:

  • vi ~/.bashrc
  • 写入 export LD_LIBRARY_PATH=动态库路径 保存
  • source ~/.bashrc,再重启终端 —> 让修改后的 .bashrc 生效
  • 执行 ./test

在这里插入图片描述

四、对比

1、静态库优缺点

  • 静态库的加载速度快
  • 发布程序无需提供静态库,移植方便
  • 消耗系统资源,浪费内存
  • 更新、部署和发布麻烦

2、动态库优缺点

  • 可以实现进程间的资源共享
  • 更新、部署、发布简单
  • 可以控制何时加载动态库
  • 加载速度比较慢
  • 发布程序时需要提供依赖的动态库

我的qq:2442391036,欢迎交流!


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
静态库动态库是在软件开发中常用的两种库文件形式。下面我会分别介绍一下它们的制作过程。 1. 静态库制作静态库是在链接时被完整地复制到可执行程序中的库文件,它包含了函数和数据的实现。静态库制作分为以下几个步骤: - 编写源代码并编译成目标文件(.o或.obj文件):使用编译器将源代码编译成目标文件。例如,使用 GCC 编译器可以执行以下命令:`gcc -c mylib.c -o mylib.o`。 - 将目标文件打包成静态库文件:使用静态库打包工具(如ar)将目标文件打包成静态库文件。例如,使用 ar 工具可以执行以下命令:`ar rcs libmylib.a mylib.o`。这将生成名为 libmylib.a 的静态库文件。 - 将生成的静态库文件与头文件一起发布:将生成的静态库文件 libmylib.a 与相关的头文件一起提供给其他开发者使用。 2. 动态库制作动态库是在运行时被动态加载的库文件,它可以在多个程序之间共享。动态库制作分为以下几个步骤: - 编写源代码并编译成目标文件(.o或.obj文件):同样,使用编译器将源代码编译成目标文件。例如,执行以下命令:`gcc -c -fPIC mylib.c -o mylib.o`。注意,这里加入了 `-fPIC` 参数,以生成位置无关的代码。 - 将目标文件打包成动态库文件:使用动态库打包工具(如gcc)将目标文件打包成动态库文件。例如,执行以下命令:`gcc -shared mylib.o -o libmylib.so`。这将生成名为 libmylib.so 的动态库文件。 - 将生成的动态库文件与头文件一起发布:将生成的动态库文件 libmylib.so 与相关的头文件一起提供给其他开发者使用。 制作完成后,其他开发者可以使用静态库动态库来链接到他们的程序中,以使用库中提供的函数和数据。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

须尽欢~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值