静态链接库和动态链接库

引子

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+引用的库=> 可执行文件;

缺点

  1. 静态库在内存中可能造成空间浪费。
    如100个进程都使用了静态库A,则内存中有100份占用。
  2. 更新库不灵活。

动态库(又称共享库)

链接阶段:
不加入引用的库。推迟到运行时。
运行时:
动态加载.so,.dll文件。

缺点

多了运行时计算符号链接的开销,但是这个开销不大。

所以jni只能使用动态链接库。(linux的话就是so文件)

gcc相关参数

https://colobu.com/2018/08/28/15-Most-Frequently-Used-GCC-Compiler-Command-Line-Options/

-fPIC: 产生位置无关的代码;
-shared: 产生共享库;(动态库)
例子:

1
2
gcc -c -Wall -Werror -fPIC Cfile.c
gcc -shared -o libCfile.so Cfile.o

-static: 生成静态链接的文件
例子:

1
gcc main.c -static -o main -lpthread

推荐文章