引文

库文件是计算机上的一类文件,可以理解为一种代码仓库,提供给使用者一些可以直接使用的变量、函数或类。

库文件分为两类:

  • 静态库:在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
  • 动态库:动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。

1. 静态库

1.1 静态库的制作

  • 命名规则:
  • Linux:libxxx.a
  • lib: 前缀,固定
  • xxx:库的名称,自起
  • .a: 后缀,固定
  • Windows:libxxx.lib
  • 静态的制作
  • gcc 获得 .o 文件
  • 将 .o 文件打包,使用 ar(archive) 工具

命令:ar rcs libxxx.a xxx.o xxx.o

eg: arc rcs libsuanshu.a sub.o add.o mult.o div.o

1.2 静态库的使用

android指定动态库路径 安卓静态库和动态库_动态库

ydh@ubuntu:~/static_lib$ gcc main.c -o dest -I include/ -l calc -L lib/

解释如下:

-I include/:生成目标文件所需头文件路径

-l calc:调用的库的名称

-L lib/:调用的库的路径

注:调用静态库依旧需要附带头文件,比如上述例子中的静态库calc包含了add.o、sub.o、mult.o、div.o的函数体,但是我们依旧需要头文件 head.h 来告诉我们有哪些函数。

head.h 的内容如下:

#ifndef _HEAD_H
#define _HEAD_H

// 加法
int add(int a, int b);
// 减法
int subtract(int a, int b);
// 乘法
int multiply(int a, int b);
// 除法
double divide(int a, int b);

#endif

2. 动态库

2.1 动态库的制作

  • 命名规则
  • Linux:libxxx.so
  • lib:前缀,固定
  • xxx:库的名称,自定
  • .so :后缀,固定
  • Windows:libxxx.dll
  • 动态库的制作
  • gcc 得到和位置无关的代码
gcc -c -fpic/-fPIC a.c b.c
  • gcc 得到动态库
gcc -shared a.o b.o -o libcalc.so

2.2 动态库的使用

android指定动态库路径 安卓静态库和动态库_静态库_02

报错原因:动态库是程序运行期间动态加载到程序中的,当找不到依赖的文件时报错

此时,可以通过 ldd(list dynamic dependencies)命令查看动态库依赖关系

android指定动态库路径 安卓静态库和动态库_静态库_03

2.3 动态库加载失败的解决方法

既然上述问题是因为无法找到动态(共享)库的位置,那我们如何定位动态库呢?

当系统加载可执行代码时,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so来完成的,它先后搜索elf文件的DT_RPATH段–>环境变量LD_LIBRARY_PATH–>/etc/ld.so.cache文件列表–>/lib/,/usr/lib目录找到库文件后将其载入内存

  • 方式一:直接在终端进行配置。这种配置方式只在当前终端有效。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库路径

注:$ 为取值,:为拼接,上述命令表示将原来的动态库路径加上新的动态库路径

android指定动态库路径 安卓静态库和动态库_linux_04

  • 方式二:用户级别的,修改 .bashrc 文件,并重启该文件配置
vim .bashrc		// 在文件的最后一行加上方式一的配置语句并退出(ESC + :wq)
. .bashrc		// 第一个点相当于source,即source bashrc
  • 方式三:系统级别,修改 /etc/profile 文件,并重启该文件配置
vim /etc/profile	// 在文件的最后一行加上方式一的配置语句并退出(ESC + :wq)
. /etc/profile		// 第一个点相当于source,即source /etc/profile

3. 静态库与动态库的区别

  • 静态库优缺点
  • 优点
  • 静态库被打包到应用程序中加载速度快
  • 发布程序无需提供静态库,移植方便
  • 缺点
  • 消耗系统资源、浪费内存
  • 更新、部署、发布麻烦
  • 动态库优缺点
  • 优点
  • 可以实现进程间资源共享
  • 更新、部署、发布简单
  • 可以控制何时加载动态库
  • 缺点
  • 加载速度比静态库慢
  • 发布时需要提供依赖的动态库

说明: 参考视频https://www.nowcoder.com/study/live/504