前言

Linux下动态库文件的命名规范是以lib开头,紧接着是动态库名,以.so为后缀名,即lib + 动态库名+.so

动态库查找过程

在Linux下,动态库的搜索的优先级顺序为:

  • 编译目标代码时指定的动态库搜索路径,保存在.dynamic段中,由DT_NEED类型的项表示;
  • 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
  • 配置文件/etc/ld.so.conf中指定的动态库搜索路径;
  • 默认的动态库搜索路径/lib/usr/lib

使用ldconfig机制

ldconfig是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享。ldconfig默认的主要功能是在/lilb/usr/lib以及配置文件/etc/ld.so.conf内所指定的路径下,搜索可用的动态链接库文件(库文件的格式为:lib***.so.**),并创建缓存文件供动态链接程序(ld.so)使用。缓存文件默认为/etc/ld.so.cache,该文件保存已排好序的动态链接库名字列表。 ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

环境变量

LD_LIBRARY_PATH

程序运行时,可以使用LD_LIBRARY_PATH环境变量临时指定程序所需引用的动态库的所在路径。

shell # LD_LIBRARY_PATH=/root/Workspace/CCode/test_dynamic_link ./main
Result: 15.

LD_PRELOAD

LD_PRELOAD可以指定程序预先需要装载的一些动态库。在LD_PRELOAD中配置的动态库会优先于正常规则指定搜索的动态库进行加载,并且无论程序是否依赖这些库,都会进行装载。由于全局符号介入机制的存在,LD_PRELOAD里面指定的动态库的全局符号会覆盖后面加载的同名全局符号,基于这点,我们可以很容易替换标准C库提供的函数接口,从而自定义库函数实现。

LD_DEBUG

LD_DEBUG用于打开动态链接器的调试功能,在设置这个变量时,动态链接器会在运行时打印出指定的信息。LD_DEBUG支持设置的值如下所示:

  • files:打印整个装载过程中,程序依赖的动态库、装载步骤以及装载地址等信息;
  • bindings:显示动态链接的符号绑定过程;
  • libs:显示动态库的查找过程;
  • versions:显示符号的版本依赖关系;
  • reloc:显示重定位过程;
  • symbols:显示符号表查找过程;
  • statistics:显示动态链接过程中的各种统计信息;
  • all:显示以上所有信息;
  • help:显示上面的各种可选值的帮助信息。

动态库的创建与使用

为了对动态库有个更直观的认识,这里使用下面的代码说明在Linux平台下如何创建和使用动态库库:

iOS 怎么查看是动态库_iOS 怎么查看是动态库


使用gcc将addvec.cmulvec.c编译成一个动态共享库文件,操作如下:

iOS 怎么查看是动态库_服务器_02


其中:

  • -shared选项:指定链接器创建一个动态共享库文件;
  • -fPIC选项:指定编译器生成位置无关的代码。

链接动态库

为了使用生成的动态库,我们在代码里调用libvector.so提供的外部接口:

#include <stdio.h>
#include "vector.h"

int x[2] = {1, 2};
int y[2] = {3, 4};
int z[2];

int main()
{
    addvec(x, y, z, 2);

    printf("z = [%d %d]\n", z[0], z[1]);

    return 0;
}

可以使用gcc编译main.c并指定链接libvector.so文件:
其中:

  • -L选项:指定动态库的路径;
  • -l选项:指定需要链接的动态库名。

相关参考

  • 《程序员的自我修养—链接、装载与库》
  • 《Linux二进制分析》