静态链接库与动态链接库的区别与使用

linker & lib

大体上 C 程序构建过程可以分为预编译、编译、汇编以及链接四个过程。

库的分类

库的分类备注优劣
static lib将库文件与目标文件在程序构建的链接阶段链接在一起即静态链接。它的好处是程序运行不再依赖系统中存在这样一个库文件供调用,因为它已经在程序可执行文件中了。缺点是如果同一个库被大量程序使用,那么静态链接将导致空间浪费、库有问题修复需要所有使用该库的程序重新编译。
dynamic lib动态库的链接是在程序执行的时候被链接的。动态库的出现正弥补了静态库的以上弊端。劣势是如果系统不存在程序所需的动态库,那程序将无法运行。运行速度稍逊,但在如今的硬件能力面前不值一提,因此动态链接使用非常广泛。

库的创建及使用

创建目录如下:

.
├── main.c
├── Makefile
└── so.c
// main.c
#include <stdio.h>

extern void hello(void);

int main()
{
        printf("call func in the so\n");
        hello();

        return 0;
}

// so.c
#include <stdio.h>

void hello(void)
{
        printf("Hello world\n");
}

// Makefile
CC=aarch64-linux-gnu-

a.out: libso.so a_static.out main.c
        ${CC}gcc main.c -lso -L. -o $@

a_static.out: libso.a main.c
        ${CC}gcc main.c -lso -L. -o $@ -static

libso.so: so.c
        ${CC}gcc -shared so.c -o $@

libso.a: so.c
        ${CC}gcc -c so.c -o so.o
        ${CC}ar -r $@ so.o

.PHONY: clean

clean:
        ${RM} -rf *.so *.a *.out *.o

在当前目录下执行 make 命令得到如下文件。其中 a_static.out 是通过与 libso.a 静态链接而来,a.out 是通过与 libso.so 动态链接而来。

.
├── a.out
├── a_static.out
├── libso.a
├── libso.so
├── main.c
├── Makefile
├── so.c
└── so.o

-l 提示 linker 寻找名为 libxxx.alibxxx.so 的库
-L 提示 linker 去哪些目录下寻找 -l 指定的库

生成动态链接库使用 -shared 选项
生成静态库则使用 ar 命令将 .o 文件打包即可。

动态链接的程序要运行需要指定库路径,否则运行会报错。
方法可以是:

  1. 把当前路径加到 /etc/ld.so.conf 中,然后运行 ldconfig
  2. 以当前路径为参数运行 ldconfig
  3. 将当前路径添加到环境变量 LD_LIBRARY_PATH 中,export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
  4. 将动态库拷到 /lib /usr/lib 路径下,原因是操作系统默认会从上述路径中找动态库

推荐使用方法3,即通过环境变量的方式来指定动态库路径,这样影响最小。

动态库的原理

这部分挖个坑,之后再谈 😃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值