当前位置: 首页 > news >正文

c++动态链接库

1. 生成动态链接库

首先实现一个动态链接库的代码

// example.cpp
#include <iostream>
void sayHello() {std::cout << "Hello from shared library!" << std::endl;
}int add(int a, int b) {return a + b;
}
// example.h
#pragma once
void sayHello()
int add(int a, int b)

使用 g++ 编译器将源代码编译为动态链接库:

g++ -fPIC -shared -o libexample.so example.cpp
  • -fPIC 表示生成位置无关代码(Position-Independent Code),这是创建共享库所必需的。

  • -shared 指示编译器生成一个共享库。

  • -o libexample.so 指定输出文件的名称。

2. 使用动态链接库

要使用这个动态链接库,需要确保在运行程序时能够找到这个库。创建一个使用这个库的程序 main.cpp:

// main.cpp
#include "example.h"int main() {sayHello();return 0;
}

编译这个程序,并链接到你的动态链接库:

g++ -o main main.cpp -L. -lexample -I.
  • -L. 告诉编译器在当前目录下查找库。
  • -lexample 告诉编译器链接名为 libexample.so 的库(注意前面的 lib 前缀和 .so 后缀)。
  • -I. 告诉编译器在当前目录下查找头文件

3. 动态链接库查找路径

3.1 默认路径

GCC默认会在/lib、/usr/lib等目录中搜索动态库。例如我们常用的#include <iostream>只引用过头文件,从来没见过cpp文件。这是因为iostream就是系统给我提供的动态库文件,so的地址就存储在默认的lib下

3.2 编译时路径

编译时-L选项并不影响环境变量 LD_LIBRARY_PATH,只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径。当程序运行时,系统还是会到默认路径下查找该程序所需要的库,如果找不到,会出现类似 cannot open shared object file 的错误。

gcc -o my_program my_program.o -L/path/to/library -llibrary_name
​​编译阶段的库查找​​顺序

链接器(如 ld)在编译时按以下优先级搜索动态库:

  • ​​显式路径​​
    • -L 指定的路径(最高优先级)。
    • -rpath-link 指定的间接依赖库路径。
  • ​​环境变量​​
    • LIBRARY_PATH 定义的路径(优先于系统默认路径)。仅在编译阶段生效,用于补充 -L 未覆盖的路径
  • 系统内置路径​​
    • 链接器预定义的 SEARCH_DIR(如 /usr/lib、/lib)。
    • 默认系统路径(如 /usr/local/lib)
3.3 运行时路径rpath

编译时通过 -rpath 指定运行时动态库搜索路径(RPATH),核心作用是​​将动态库的路径硬编码到可执行文件或动态库中​​,从而在程序运行时直接按此路径加载依赖库,无需依赖环境变量或系统默认路径。优先级高于 LD_LIBRARY_PATH 和系统默认路径

gcc -o my_program my_program.o -L/path/to/library -llibrary_name -Wl,-rpath,/path/to/library

可以通过readelf -d my_program | grep RUNPATH来查看二进制的rpath路径

3.4 运行时路径LD_LIBRARY_PATH

LD_LIBRARY_PATH 是 ​​运行时​​ 环境变量,用于指定程序加载时动态链接库的搜索路径。它影响的是程序启动后操作系统加载动态库的行为,与编译阶段无关

当前开发中并没有使用rpath,依然使用LD_LIBRARY_PATH

3.5 示例
​​编译时依赖

编译时指定库路径(-L)和链接库名(-l)

gcc main.c -L/path/to/libs -lfoo -Wl,-rpath=/path/to/libs
  • -L 确保链接时找到 libfoo.so;
  • -rpath 确保运行时自动加载该库,无需依赖 LD_LIBRARY_PATH。
​​运行时依赖​​

若未使用 -rpath,需在运行前设置:

export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
./a.out

ldd命令

通过ldd可以查看二进制依赖的动态链接库已经执行时查询的地址。有时候会发现有些动态库为not found,是因为执行时在LD_LIBRARY_PATH和默认路径下没有找到动态库,我们可以把依赖的动态库地址添加到LD_LIBRARY_PATH中

ldd其实就是模拟二进制运行时的链接过程。

相关文章:

  • 电子电路:电位器和可变电阻是同一个东西吗?
  • CT重建笔记(五)—2D平行束投影公式
  • [已解决] LaTeX “Unicode character“ 报错 (中文字符处理)
  • 硬件工程师笔记——二极管Multisim电路仿真实验汇总
  • 给图表组件上点“颜色” —— 我与 CodeBuddy 的合作记录
  • 赋能企业级移动应用 CFCA FIDO+提升安全与体验
  • 实物工厂零件画图案例(中)
  • 56.合并区间(java)
  • 【言语理解】逻辑填空之词义辨析(10)
  • 力扣HOT100之二叉树:108. 将有序数组转换为二叉搜索树
  • 45 python csv(存储表格数据)
  • No More Adam: 新型优化器SGD_SaI
  • 前端二进制数据指南:从 ArrayBuffer 到高级流处理
  • 【鸿蒙开发避坑】使用全局状态变量控制动画时,动画异常甚至动画方向与预期相反的原因分析以及解决方案
  • C语言_动态内存管理
  • vue引用cesium,解决“Not allowed to load local resource”报错
  • ProfibusDP主站转modbusTCP网关与ABB电机保护器数据交互
  • 典籍知识问答模块AI问答bug修改
  • 信息与信息化
  • LeetCode 第 45 题“跳跃游戏 II”
  • 侵害孩子者,必严惩不贷!3名性侵害未成年人罪犯今日执行死刑
  • 老字号“逆生长”,上海制造的出海“蜜”钥
  • 车建兴被留置:跌落的前常州首富和红星系重整迷路
  • 西班牙政府排除因国家电网遭攻击导致大停电的可能
  • 市场监管总局召开平台企业支持个体工商户发展座谈会
  • 冰雹造成车损能赔吗?如何理赔?机构答疑