在 Linux 中,动态库(.so文件)的调用方式主要有两种:编译时链接(隐式调用)和运行时加载(显式调用)。
一、编译时链接(隐式调用)
这种方式在编译阶段就指定动态库,程序启动时会自动加载依赖的动态库,适用于已知库路径和接口的场景。
- 步骤 1:创建动态库源文件
首先实现一个简单的动态库,包含两个接口函数。
- 步骤 2:编译生成动态库
使用g++编译生成.so文件:
# 编译为位置无关代码(-fPIC),生成动态库(-shared)
g++ -fPIC -shared mylib.cpp -o libmylib.so
生成libmylib.so动态库(Linux 动态库命名规范:lib+库名+.so)。
- 步骤 3:编写调用动态库的程序
- 步骤 4:编译程序并链接动态库
# -L. 表示在当前目录查找动态库,-lmylib 表示链接libmylib.so
g++ main.cpp -o main -L. -lmylib
+ 步骤 5:运行程序 运行前需确保系统能找到动态库(否则会报 “找不到共享库” 错误):
# 临时指定动态库搜索路径(当前目录)
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH#运行程序
./main
二、运行时加载(显式调用)
这种方式不依赖编译时链接,而是在程序运行中通过系统函数动态加载库并调用接口,适用于库路径不确定或需要动态切换库版本的场景(如插件系统)。
- 步骤 1:使用相同的动态库
复用前面生成的libmylib.so(无需修改)。
- 步骤 2:编写显式调用的程序
通过dlopen、dlsym、dlclose等函数手动加载和调用动态库。
- 步骤 3:编译程序
显式调用需要链接dl库(动态加载系统库)
g++ main_dl.cpp -o main_dl -ldl
- 步骤 4:运行程序
同样需要指定动态库路径
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main_dl
输出结果与隐式调用相同。