做网站开发的有外快嘛,搜索引擎营销的6种方式,常用的广州网站建设,自己动手做一个网页个人主页#xff1a;chian-ocean
文章专栏-Linux
前言 动静态库是编程中两种主要的库类型#xff0c;它们用于帮助开发者复用已有的代码#xff0c;而不需要每次都从头开始编写。它们的主要区别在于链接和加载的时机、方式以及使用场景 库
库就是一些已经写好并且经过测试…个人主页chian-ocean
文章专栏-Linux
前言 动静态库是编程中两种主要的库类型它们用于帮助开发者复用已有的代码而不需要每次都从头开始编写。它们的主要区别在于链接和加载的时机、方式以及使用场景 库
库就是一些已经写好并且经过测试的功能模块你只需要在自己的程序中“借用”这些功能而无需重新做同样的工作。这样不仅节省了时间还能提高代码的质量和稳定性。
库的形式
库的形式主要有两种分别是 静态库 和 动态库。它们的区别在于程序如何使用这些库以及库文件在程序中的存储方式。
静态库 (Static Library)
静态库是在程序编译时就被链接到可执行文件中的库所有的库代码会被嵌入到最终生成的程序中。程序在运行时不再依赖外部的库文件。
文件扩展名
Linux/Unix 系统.aarchiveWindows 系统.lib 动态库 (Dynamic Library)
动态库是在程序运行时加载的库程序并不会将库的代码嵌入到程序中而是在程序启动时或者在程序运行时动态加载需要的库文件。
文件扩展名
Linux/Unix 系统.soShared ObjectWindows 系统.dllDynamic Link Library
总结
特性静态库动态库链接时机编译时链接库代码被嵌入到程序中运行时链接程序在执行时动态加载库可执行文件大小程序文件较大因为库代码被包含在其中程序文件较小只包含对库的引用库的代码在外部依赖关系不依赖外部库文件所有代码在可执行文件中依赖外部库文件程序必须确保运行时找到对应的库文件共享每个程序都包含自己需要的库代码不共享多个程序可以共享同一个库文件节省内存和磁盘空间更新库文件更新时需要重新编译程序库文件更新时无需重新编译程序只需要确保兼容性性能程序启动较快因为所有代码都已经包含在内程序启动时需要加载库文件可能稍慢且可能会有额外的内存管理开销
静态库
静态库的制作
**静态库Static Library**是一个打包了多个目标文件.o 文件或其他库文件的归档文件。它可以在编译时链接到程序中生成最终的可执行文件。静态库的扩展名通常为 .a在 Unix/Linux 系统上。
编写源文件 创建包含函数实现的 .c 文件例如 math.c。
简单的加减乘除。
#include mymath.h int errno 0 ;
int add(int x,int y)
{ return x y;
}
int sub(int x,int y)
{ return x - y;
}
int mul(int x,int y)
{ return x * y;
}
int div(int x,int y)
{ if(y 0) { errno -1; return -1; } return x / y;
}编写头文件 创建包含函数实现的 .c 函数声明
#pragma once
#include stdio.h
extern int errno; int add(int x,int y);
int sub(int x,int y);
int mul(int x,int y);
int div(int x,int y); 编写Makefile创建自动化构建文件
# 定义静态库的名称
liblibmath.a # 生成静态库 libmath.a 的规则
# 依赖 mymath.o 文件并将其打包成静态库
$(lib): mymath.o # 使用 ar 命令将目标文件 mymath.o 添加到静态库 libmath.a 中ar -rc $ $^# 编译 mymath.c 文件为 mymath.o 目标文件的规则
mymath.o: mymath.c # 使用 gcc 编译 mymath.c 文件为目标文件 mymath.ogcc -c $^# 定义伪目标 clean它用于清理构建产生的文件
.PHONY: clean
clean: # 删除所有目标文件 (.o) 和库文件 (lib*)rm -rf *.o lib* # 定义伪目标 output它用于创建输出目录并复制必要的文件
.PHONY: output
output: # 创建 lib/include 目录mkdir -p lib/include # 创建 lib/libmymath 目录mkdir -p lib/libmymath # 将所有头文件复制到 lib/include 目录cp *.h lib/include # 将静态库 (.a 文件) 复制到 lib/libmymath 目录cp *.a lib/libmymath
静态库的使用
#include mymath.h // 包含自定义的头文件 mymath.hint main() {printf(add(1 1) %d\n, add(1, 1));printf(sub(1 1) %d\n, sub(1, 1));printf(mul(1 1) %d\n, mul(1, 1));printf(div(1 1) %d\n, div(1, 1));return 0;
}
写一个代码利用自己写的库
此时的静态库在/lib/libmymath的路径下。头文件在/lib/include的路径下。可执行程序在/mian的目录下。
库路径和头文件路径只有用户知道
gcc main.c -I ../lib/include/ -L ../lib/libmymath/ -lmymathgcc main.c使用 gcc 编译器来编译 main.c 文件。 -I ./lib/include/这个选项告诉编译器在 ./lib/include/ 目录中查找头文件 (*.h)。-I 后面跟着的是头文件所在的目录。 -L ./lib/libmymath/这个选项告诉编译器在 ./lib/libmymath/ 目录中查找库文件 (*.a 或 *.so)-L 后面跟的是库文件所在的目录。 -lmymath这个选项告诉编译器链接 libmymath 库。编译器会自动查找并链接名为 libmymath.a 或 libmymath.so 的库文件。注意lib 前缀和 .a 后缀会被自动省略。
库路径和头文件路径在系统路径下
/usr/lib64 #库的系统默认路径/usr/include #头文件的系统默认路径这时候我们仅仅需要手动连接库就好了。
gcc main.c -lmymath动态库
动态库的制作
把静态库的的方法做成动态库。
编写Makefile创建自动化构建文件
# 定义变量dy_mymath表示生成的动态库文件名
dy_mymath libmymath.so# 生成动态库 libmymath.so 目标
# 该目标依赖于 mymath.o 文件
$(dy_mymath): mymath.o# 使用gcc命令生成动态库-shared 表示生成共享库-o 用于指定输出文件# $ 代表目标文件这里是 libmymath.so$^ 代表所有依赖文件这里是 mymath.ogcc -shared -o $ $^# 生成目标文件 mymath.o
# 该目标依赖于 mymath.c 文件
mymath.o: mymath.c# 使用gcc编译源文件 mymath.c 生成目标文件 mymath.o# -fPIC 生成位置无关代码适用于动态库-c 只编译源文件不进行链接# $^ 代表依赖文件这里是 mymath.cgcc -fPIC -c $^# 声明 clean 为伪目标表示 make clean 是一个命令而不是文件
.PHONY: clean# clean 目标用于清理生成的目标文件和动态库文件
clean:# 删除所有目标文件 (.o) 和共享库文件 (.so)# -rf 强制删除不询问确认rm -rf *.o *.so
动态库的使用
库路径和头文件路径只有用户知道 gcc main.c -I ../ -L ../ -lmymath-I../此选项指定了头文件路径告诉编译器去 ../ 目录下查找头文件。 -L../此选项指定了库文件路径告诉链接器去 ../ 目录下查找库文件。 -lmymath告诉编译器链接 libmymath.so 动态库。链接器会自动在路径中查找名为 libmymath.so 的动态库文件。
库路径和头文件路径在系统路径下
/usr/lib64 #库的系统默认路径/usr/include #头文件的系统默认路径这时候我们仅仅需要手动连接库就好了。
gcc main.c -lmymath执行可执行程序的时候就会报错 ./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory这个错误表明 动态库 libmymath.so 无法被加载通常是因为系统在运行时无法找到该动态库。
动态库的加载 将动态库加载到lib64系统路径下拷贝到系统默认搜索的路径的下面 软链接到lib64的系统路径下。
sudo ln -s /home/ocean/linux/file/lib_dyn/libmymath.so /lib64将其软连接到系统路径下。 运行程序时指定动态库路径 如果运行时无法找到动态库使用 LD_LIBRARY_PATH 来指定动态库的位置(临时。
export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/home/ocean/linux/file/lib_dyn在/etc/ld.so.conof.d建立自己的动态库的路径配置文件然后执行ldconfig进行刷新。 同样也可以进行动态库的加载。