📌 静态库和动态库的制作与使用指南
🚀 静态库的制作与使用
1. 创建静态库
-
编写源代码
- 创建用于实现功能的
.c
文件和相应的头文件(.h
)。 - 例如,我们有
add.c
和相应的头文件add.h
。
add.h
:#ifndef ADD_H #define ADD_H int add(int a, int b); #endif
add.c
:#include "add.h" int add(int a, int b) { return a + b; }
- 创建用于实现功能的
-
编译生成目标文件(.o 文件)
- 使用
gcc
将源代码编译为目标文件:
gcc -c add.c -o add.o
- 使用
-
创建静态库(.a 文件)
- 使用
ar
命令创建静态库:
ar rcs libmylib.a add.o
libmylib.a
是生成的静态库文件。
- 使用
2. 使用静态库
-
编写主程序
- 编写一个调用静态库中函数的主程序,例如
main.c
:
#include <stdio.h> #include "add.h" int main() { int result = add(3, 4); printf("Result: %d\n", result); return 0; }
- 编写一个调用静态库中函数的主程序,例如
-
编译并链接静态库
- 使用
gcc
编译主程序并链接静态库:
gcc main.c -o main -I. -L. -lmylib
-I.
指定头文件目录,-L.
指定库文件目录,-lmylib
用于链接静态库(省略lib
前缀和.a
后缀)。
- 使用
🚀 动态库的制作与使用
1. 创建动态库
-
编写源代码
- 动态库的源代码和静态库类似,例如
sub.c
和相应的头文件sub.h
。
sub.h
:#ifndef SUB_H #define SUB_H int sub(int a, int b); #endif
sub.c
:#include "sub.h" int sub(int a, int b) { return a - b; }
- 动态库的源代码和静态库类似,例如
-
编译生成目标文件
- 使用
-fPIC
选项编译源代码,生成位置无关代码:
gcc -fPIC -c sub.c -o sub.o
- 使用
-
创建动态库(.so 文件)
- 使用
-shared
选项创建动态库:
gcc -shared -o libmylib.so sub.o
libmylib.so
是生成的动态库文件。
- 使用
2. 使用动态库
-
编写主程序
- 编写一个调用动态库中函数的主程序,例如
main.c
:
#include <stdio.h> #include "sub.h" int main() { int result = sub(7, 3); printf("Result: %d\n", result); return 0; }
- 编写一个调用动态库中函数的主程序,例如
-
编译并链接动态库
- 使用
gcc
编译主程序并链接动态库:
gcc main.c -o main -I. -L. -lmylib -Wl,-rpath=.
-Wl,-rpath=.
设置动态库搜索路径。
- 使用
-
运行程序
- 如果动态库不在默认路径中,运行程序时需要设置
LD_LIBRARY_PATH
:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main
- 如果动态库不在默认路径中,运行程序时需要设置
🔄 静态库 vs 动态库
- 静态库:在链接时,将库的代码打包到可执行程序中。生成的可执行文件较大,但无需额外的库文件支持。
- 动态库:在运行时加载,库文件与可执行程序分离,减少了可执行文件的大小,但需要在运行时找到库文件。
总结
- 静态库 使用
ar
命令创建,链接时直接打包到可执行文件中。 - 动态库 使用
-shared
选项创建,运行时动态加载,链接时需要设置-Wl,-rpath
或环境变量LD_LIBRARY_PATH
。
但是一般情况下 我们的代码结构是这样的
include包含头文件 lib是制作的库文件 src是源文件的.c代码,testcode是我们的测试代码
现在开始这个流程
📌 多文件静态库和动态库的制作
🚀 静态库的制作与使用
1. 创建静态库
-
编写源代码
- 创建用于实现功能的
.c
文件和相应的头文件(.h
)。 - 例如,我们有
add.c
、sub.c
及其相应的头文件add.h
、sub.h
。
add.h
:#ifndef ADD_H #define ADD_H int add(int a, int b); #endif
add.c
:#include "add.h" int add(int a, int b) { return a + b; }
sub.h
:#ifndef SUB_H #define SUB_H int sub(int a, int b); #endif
sub.c
:#include "sub.h" int sub(int a, int b) { return a - b; }
- 创建用于实现功能的
-
编译生成目标文件(.o 文件)
- 使用
gcc
将源代码编译为目标文件:
gcc -c src/add.c -o src/add.o gcc -c src/sub.c -o src/sub.o
- 使用
-
创建静态库(.a 文件)
- 使用
ar
命令创建静态库:
ar rcs lib/libmylib.a src/add.o src/sub.o
libmylib.a
是生成的静态库文件。
- 使用
2. 使用静态库
-
编写主程序
- 编写一个调用静态库中函数的主程序,例如
test.c
:
#include <stdio.h> #include "add.h" #include "sub.h" int main() { int result1 = add(3, 4); int result2 = sub(7, 3); printf("Result (add): %d\n", result1); printf("Result (sub): %d\n", result2); return 0; }
- 编写一个调用静态库中函数的主程序,例如
-
编译并链接静态库
- 使用
gcc
编译主程序并链接静态库:
gcc testcode/test.c -o testcode/test -Iinclude -Llib -lmylib
-Iinclude
指定头文件目录,-Llib
指定库文件目录,-lmylib
用于链接静态库(省略lib
前缀和.a
后缀)。
- 使用
🚀 动态库的制作与使用
1. 创建动态库
-
编写源代码
- 创建用于实现功能的
.c
文件和相应的头文件,例如mul.c
和div.c
及其相应的头文件mul.h
和div.h
。
mul.h
:#ifndef MUL_H #define MUL_H int mul(int a, int b); #endif
mul.c
:#include "mul.h" int mul(int a, int b) { return a * b; }
div.h
:#ifndef DIV_H #define DIV_H int div(int a, int b); #endif
div.c
:#include "div.h" int div(int a, int b) { return a / b; }
- 创建用于实现功能的
-
编译生成目标文件
- 使用
-fPIC
选项编译源代码,生成位置无关代码:
gcc -fPIC -c src/mul.c -o src/mul.o gcc -fPIC -c src/div.c -o src/div.o
- 使用
-
创建动态库(.so 文件)
- 使用
-shared
选项创建动态库:
gcc -shared -o lib/libmylib.so src/mul.o src/div.o
libmylib.so
是生成的动态库文件。
- 使用
2. 使用动态库
-
编写主程序
- 编写一个调用动态库中函数的主程序,例如
test.c
:
#include <stdio.h> #include "mul.h" #include "div.h" int main() { int result1 = mul(3, 4); int result2 = div(8, 2); printf("Result (mul): %d\n", result1); printf("Result (div): %d\n", result2); return 0; }
- 编写一个调用动态库中函数的主程序,例如
-
编译并链接动态库
- 使用
gcc
编译主程序并链接动态库:
gcc testcode/test.c -o testcode/test -Iinclude -Llib -lmylib -Wl,-rpath=lib
-Wl,-rpath=lib
设置动态库搜索路径。
- 使用
-
运行程序
- 如果动态库不在默认路径中,运行程序时需要设置
LD_LIBRARY_PATH
:
export LD_LIBRARY_PATH=lib:$LD_LIBRARY_PATH ./testcode/test
- 如果动态库不在默认路径中,运行程序时需要设置
🔄 静态库 vs 动态库
- 静态库:在链接时,将库的代码打包到可执行程序中。生成的可执行文件较大,但无需额外的库文件支持。
- 动态库:在运行时加载,库文件与可执行程序分离,减少了可执行文件的大小,但需要在运行时找到库文件。
总结
- 静态库 使用
ar
命令创建,链接时直接打包到可执行文件中。 - 动态库 使用
-shared
选项创建,运行时动态加载,链接时需要设置-Wl,-rpath
或环境变量LD_LIBRARY_PATH
。