引子
JNI
的时候发现要使用so
文件、动态链接库,那么究竟什么是动态链接库呢?
参考:
https://www.zhihu.com/question/20484931
概念
库有两种:静态库和动态库。
静态库: .a
,.lib
;
动态库:.so
,.dll
;windows
:.lib
,.dll
;linux
:.a
,.so
;
非库:
生成.o
文件: g++ -c hellospeak.cpp
;
// 只产生编译的代码(没有链接link)
生成.out
文件: g++ hellospeak.cpp speak.cpp -o hellospeak
;
// 执行完整的编译过程,并且生成一个a.out文件。
链接过程
源文件(.h
,.cpp
)
=>预编译=>编译=>汇编
=>链接
=>可执行文件
这里我们主要关心链接阶段。
静态库
链接阶段:
汇编生成的.o
+引用的库=> 可执行文件;
缺点
- 静态库在内存中可能造成空间浪费。
如100个进程都使用了静态库A,则内存中有100份占用。 - 更新库不灵活。
动态库(又称共享库)
链接阶段:
不加入引用的库。推迟到运行时。
运行时:
动态加载.so
,.dll
文件。
缺点
多了运行时计算符号链接的开销,但是这个开销不大。
所以jni只能使用动态链接库。(linux的话就是so
文件)
gcc相关参数
https://colobu.com/2018/08/28/15-Most-Frequently-Used-GCC-Compiler-Command-Line-Options/
-fPIC
: 产生位置无关的代码;-shared
: 产生共享库;(动态库)
例子:
1 | gcc -c -Wall -Werror -fPIC Cfile.c |
-static
: 生成静态链接的文件
例子:
1 | gcc main.c -static -o main -lpthread |