制作与使用动态库与静态库

一. 定义

1. 动态库和静态库

一个库主要包含一批头文件和一个或多个源文件。头文件包含函数声明,源文件包含函数实现。

动态库: 在Linux下是后缀为.so文件,在Windows下是后缀为.dll文件。多个程序可以共享使用动态库代码。

静态库: 在Linux下是后缀为.a的文件,在Windows下是后缀为.lib的文件。

2. 动态链接和静态链接

动态链接: 在可执行程序运行前,操作系统将使用到动态库的机器码从硬盘加载到内存中。

静态链接: 可执行程序编译链接时,将代码使用到的静态库的代码拷贝到可执行程序中。静态链接的本质是将使用到的代码链接。

静态链接和动态链接的优缺点

静态链接: 可执行程序文件体积大,但是不依赖库,可移植性强。
动态链接: 库执行程序文件体积小,但是依赖库,如果库被删除,该程序也无法使用。

二. 制作与使用静态库

1. 生成静态库

第一步 编写源代码文件和头文件
写一个静态库需要头文件和能生成目标文件的文件。

编写你的库函数的源代码文件(例如 add.c)和相应的头文件(例如 add.h)。

add.h

#pragma once
int add(int a, int b);

add.c

#include "add.h"

int add(int a, int b) {
    return a + b;
}

第二步 生成目标文件

使用编译器将源代码文件编译成目标文件(.o 文件)。

gcc -c add.c -o add.o

第三步 打包生成静态库

使用 ar 工具将目标文件打包成静态库。

ar rc libmymath.a add.o

ar: GNU归档工具。
rc: 选项用于替换(replace)和创建(create)归档文件,并生成索引(symbol table)。
libmymath.a: 静态库文件名。
此步骤将生成名为 libmymath.a 的静态库。

2. Makefile的发布

1 lib=libadd.a
2 
3 $(lib): myadd.o
4   ar -rc $@ $^
5 myadd.o: add.c
6   gcc -c $^
7 
8 .PHONY: clean
9 clean:
10   rm -rf *.o *.a lib
11 
12 .PHONY: output
13 output:
14   mkdir -p lib/include
15   mkdir -p lib/myaddlib
16   cp *.h lib/include
17   cp *.a lib/myaddlib
  1. 定义静态库: 第一行指定静态库名称为libadd.a。

  2. 构建规则: 第3行定义构建规则,表明静态库依赖于myadd.o,第4行实际构建静态库的命令。

  3. 编译规则: 第5-6行定义了编译myadd.o的规则,依赖于add.c,使用gcc编译。

  4. 清理规则: 第8-10行定义了清理规则,用于删除生成的目标文件和静态库。

  5. 输出目录规则: 第12-17行定义了输出目录结构的规则,包括创建目录和复制文件

3. 使用静态库

1. 编写一个使用静态库的程序 main_static.c

#include "add.h"

int main() {
    int result = add(3, 4);
    printf("Result: %d\n", result);
    return 0;
}

2. 编译使用静态库的程序
使用 gcc 编译程序并链接静态库。

gcc main_static.c -I ./lib/include/ -L ./lib/myaddlib/ -ladd

-I ./lib/include/: 告诉编译器在 ./lib/include/ 目录下查找头文件。
-L ./lib/myaddlib/: 告诉编译器在 ./lib/myaddlib/ 目录下查找库文件。
-ladd: 指定链接时使用的库名,编译器会在指定的库目录中找到 libadd.a。

可以使用软连接方式把头文件库文件添加在默认搜索路径上
(/usr/include、/usr/lib64)。
添加后直接使用运行指令

gcc main_static.c  -ladd

三. 制作与使用动态库

1. 生成动态库

第一步 生成目标文件
使用 -fPIC 选项生成位置独立的目标文件

gcc -fPIC -c add.c -o add.o

-fPIC: 生成位置独立的代码。

第二步 生成动态库
使用 -shared 选项生成动态库。

gcc -shared -o libadd.so add.o

-shared: 生成动态共享库。
libmymath.so: 动态库文件名。

第三步 生成动态库

使用 -shared 选项生成动态库。

gcc -shared -o libmymath.so add.o

-shared: 生成动态共享库。

2. 使用动态库

1. 编写一个使用动态库的程序 main_static.c

#include "add.h"

int main() {
    int result = add(3, 4);
    printf("Result: %d\n", result);
    return 0;
}

2. 加载动态库

方法1: 拷贝到系统默认的库路径
首先,我们需要将自定义库文件拷贝到系统默认的库路径中。假设你的库文件位于 /home/my/libadd.so

sudo cp /home/my/libadd.so /usr/lib64/

这将把你的库文件复制到 /usr/lib64/ 目录下。
方法2: 在系统默认库路径下建立软链接
创建一个软链接,将库文件链接到 /lib64/ 目录中。

sudo ln -s /home/my/libadd.so /lib64/libadd.so

这将在 /lib64/ 目录下创建一个名为 libadd.so 的软链接。

方法3: 将库路径添加到LD_LIBRARY_PATH
将自定义库的路径添加到系统环境变量 LD_LIBRARY_PATH 中。

export LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH

你也可以将上述命令添加到你的 shell 配置文件中(例如 ~/.bashrc 或 ~/.zshrc),以便每次打开终端时都自动设置。

方法4: 配置 /etc/ld.so.conf.d/
创建一个配置文件,告诉系统在哪里查找动态库。

sudo nano /etc/ld.so.conf.d/mymath.conf

在文件中添加你库文件所在的路径,例如:

/home/my/

保存并关闭文件。
重新运行ldconfig

sudo ldconfig

这将更新系统动态链接器的运行时链接库缓存。

现在,你的自定义库应该能够在系统中被正确找到和使用了。你可以编译和运行程序而无需手动指定库文件的路径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值