0xzhang的博客

Linux动态库调用

· 0xzhang

动态库相比静态库的区别是:静态库是编译时就加载到可执行文件中的,而动态库是在程序运行时完成加载的,所以使用动态库的程序的体积要比使用静态库程序的体积小,并且使用动态库的程序在运行时必须依赖所使用的动态库文件,而使用静态库的程序一旦完成编译,就不再需要依赖的静态库文件。

在Linux平台下,动态库的调用分为显式和隐式两种方式。

隐式调用§

又叫隐式加载或载入时加载。

通过在编译时设置包含动态库的头文件(-Idir... -include file),并指明动态库的位置和名称(-Ldir... -lnamespec(libnamespec.so))。

隐式调用由系统完成加载,对编程者透明。隐式调用必须包含动态库中的头文件。

显式调用§

在运行时加载,在程序运行过程中通过dlopen指定动态链接库文件,然后通过dlsym获取动态库里函数的地址。

相比隐式调用,显式调用需要在程序中实现,写明要加载的动态库以及调用函数的名称。

使用dlopen链接并不是在进程启动时候加载映射的,而是当进程运行到使用dlopen的地方才加载。因此如果一个程序进行显式调用,但并没有附带显式调用加载的动态库文件,该程序仍能正常启动。而且当运行逻辑没有触发调用dlopen的代码时,即使缺少动态库文件程序仍然可以正常运行。

显式调用时,由编程者实现进行加载并负责卸载。这样好比对动态申请内存空间,需要使用时申请,不使用时即可释放。因此显式调用内存使用更为合理,大型项目应使用显式调用。

常用工具§

readelf§

--dyn-syms

显示文件动态符号表中的入口。

-d

显示文件动态段内容。

ldd§

使用dlopen加载的动态库通过ldd无法查看到。

ldd -u

查看不需要链接的动态库文件。

多链接的动态库文件正是由于在编译时的设置导致,因为动态链接有加载文件的过程

-Wl,--as-needed

链接选项,仅当符号在目标文件和必要的库中无法找到时,才会从这些动态库中加载。

strace§

用于查看系统调用和信号。

通过strace可以看到程序加载了哪些动态库文件,可以看到程序通过dlopen加载的动态库文件。

参考资料§

  1. linux动态库加载的秘密 - LiuYanYGZ - 博客园
  2. linux动态库加载时搜索路径 - LiuYanYGZ - 博客园
  3. linux下动态链接库(.so)的显式调用和隐式调用_hujing_Liu-CSDN博客