链接器的工作原理,静态链接与动态链接的区别,如何创建和使用动态链接库

链接器在程序开发中的作用至关重要,它负责将多个目标文件和库文件整合成一个可以执行的文件。在深入了解链接器的工作原理、静态链接与动态链接的区别,以及如何创建和使用动态链接库之前,我们先来概述一下链接器的基本功能。

链接器的工作原理

链接器(Linker) 是负责将一个或多个目标文件与库文件组合成一个可执行文件的工具。其主要功能包括:

  1. 符号解析:识别并处理程序中所有的符号(函数和变量的名称),确保每个符号都有唯一的定义。对于引用但未定义的符号(外部符号),链接器会在提供的库或其他目标文件中查找定义。

  2. 重定位:将每个模块中的代码和数据地址调整到最终的内存地址。重定位包括代码中的地址修正和数据段的位置调整,以保证所有引用指向正确的内存位置。

  3. 合并段:将来自不同目标文件的相同类型的段(如代码段、数据段等)合并成一个连续的段。

  4. 处理库:将程序需要的库代码与目标文件链接在一起。链接器可以处理两种类型的库:静态库和动态库。

  5. 生成可执行文件:最终输出一个可以在操作系统上运行的可执行文件。

静态链接与动态链接的区别

静态链接(Static Linking)动态链接(Dynamic Linking) 是链接器的两种工作模式,它们各自有不同的特点和使用场景。

静态链接
  • 概念:在静态链接中,库代码在编译时被复制并嵌入到每个使用它的可执行文件中。这样,生成的可执行文件包含所有需要的代码,不依赖外部的库文件。

  • 优点

    • 独立性强:生成的可执行文件包含所有依赖,不需要在运行时额外的库文件。
    • 兼容性好:运行时不依赖于系统中安装的库版本,不会遇到“库版本冲突”问题。
  • 缺点

    • 文件体积大:每个可执行文件都包含完整的库代码,导致文件体积增大。
    • 更新麻烦:如果库有更新,需要重新编译所有使用该库的程序。
  • 静态库的扩展名

    • Windows: .lib
    • Unix/Linux: .a
动态链接
  • 概念:在动态链接中,库代码在运行时加载,不嵌入到可执行文件中。可执行文件只包含对库的引用,库代码在运行时由操作系统加载。

  • 优点

    • 文件体积小:可执行文件不包含库代码,只包含对库的引用。
    • 易于更新:更新库不需要重新编译程序,只需替换库文件。
    • 内存效率高:多个程序可以共享同一个库文件的内存实例,减少内存使用。
  • 缺点

    • 依赖性强:可执行文件在运行时需要能够找到并加载正确版本的库文件。
    • 兼容性问题:库文件版本不匹配可能导致程序运行失败。
  • 动态库的扩展名

    • Windows: .dll(Dynamic-Link Library)
    • Unix/Linux: .so(Shared Object)

创建和使用动态链接库

创建动态链接库

在不同的操作系统上,创建动态链接库的方法略有不同。以下是一些常见的步骤和命令:

在 Linux 上创建动态链接库
  1. 编写库代码

    创建一个C++源文件,包含我们要放在动态库中的函数。

    // example.cpp
    #include <iostream>
    
    void hello() {
        std::cout << "Hello from the dynamic library!" << std::endl;
    }
    

    2.编译为目标文件

    使用 -fPIC(Position Independent Code)标志编译源文件为目标文件。这是创建动态库的必要步骤,因为动态库中的代码需要能够在任何内存地址加载和执行。

    g++ -c -fPIC example.cpp -o example.o
    

    3.创建动态库

    使用 -shared 标志将目标文件链接为动态库。

    g++ -shared -o libexample.so example.o
    

生成的动态库文件 libexample.so 可以在程序中使用。

在 Windows 上创建动态链接库
  1. 编写库代码

    Windows上的代码编写与Linux相似,但需要使用__declspec(dllexport)指令来标识导出的函数。

    // example.cpp
    #include <iostream>
    
    __declspec(dllexport) void hello() {
        std::cout << "Hello from the dynamic library!" << std::endl;
    }
    

    2.编译为目标文件

    使用以下命令编译源文件为目标文件:

    g++ -c example.cpp -o example.o
    

    3.创建动态库

    使用 -shared 标志将目标文件链接为动态库。

    g++ -shared -o example.dll example.o
    

    生成的动态库文件 example.dll 可以在程序中使用。

使用动态链接库
在 Linux 上使用动态链接库
  1. 编写使用库的代码

    创建一个C++源文件,包含对动态库中函数的调用。

    // main.cpp
    extern void hello();
    
    int main() {
        hello();
        return 0;
    }
    

    2.编译和链接

    编译时需要指定库的路径和名称,使用 -L-l 标志。

g++ main.cpp -L. -lexample -o main

        

其中,-L. 指定库路径为当前目录,-lexample 指定库名称(lib前缀和.so扩展名可以省略)。

  3.运行可执行文件

在运行时,操作系统需要知道动态库的路径。可以使用LD_LIBRARY_PATH环境变量指定库路径。

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main

在 Windows 上使用动态链接库
  1. 编写使用库的代码

    Windows上的代码编写与Linux相似,但需要使用__declspec(dllimport)指令来标识导入的函数。

    // main.cpp
    __declspec(dllimport) void hello();
    
    int main() {
        hello();
        return 0;
    }
    

    2.编译和链接

    在编译时,需要指定库的路径和名称。

    g++ main.cpp example.dll -o main
    

    3.运行可执行文件

    确保动态库文件(example.dll)在可执行文件的同一目录或系统的PATH环境变量中指定的目录。

    ./main.exe
    

总结

  • 链接器 的主要任务是将多个目标文件和库文件合并,解析符号,重定位地址,最终生成一个可执行文件。
  • 静态链接 将库代码嵌入到可执行文件中,生成的可执行文件独立,但体积较大且更新麻烦。
  • 动态链接 在运行时加载库文件,使可执行文件体积更小,更新更灵活,但需要在运行时正确找到库文件。
  • 创建和使用动态链接库涉及编译源代码为目标文件、生成动态库、以及在编译和运行时正确指定库的路径。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/783099.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

游戏AI的创造思路-技术基础-决策树(2)

上一篇写了决策树的基础概念和一些简单例子&#xff0c;本篇将着重在实际案例上进行说明 目录 8. 决策树应用的实际例子 8.1. 方法和过程 8.1.1. 定义行为 8.1.2. 确定属性 8.1.3. 构建决策树 8.1.4. 实施行为 8.1.5. 实时更新 8.2. Python代码 8. 决策树应用的实际例子…

大模型网信办备案全网最详细说明【+流程+附件】

根据目前公开的国内大模型算法备案统计来看&#xff0c;首批境内深度合成服务算法备案清单&#xff0c;总共通过41家&#xff0c;14家互联网大厂和独角兽企业成功申报算法备案32个&#xff0c;6家新兴互联网公司成功申报算法备案9个&#xff0c;仅占比21.9%。 第二批境内…

Python标准库常用模块的典型用法介绍与案例

目录 1. os模块 典型用法 案例 2. sys模块 典型用法 案例 3. datetime模块 典型用法 案例 4. re模块 典型用法 案例 5. json模块 典型用法 案例 6. random模块 典型用法 案例 7. collections模块 典型用法 案例 总结 Python作为一门功能强大的编…

控件-ProgressBar

常用属性 1.android:max:进度条的最大值 2. android: progress:进度条已完成进度值 3. android: indeterminate:如果设置成true,则进度条不精确显示进度 4.style"?android:attr/progressBarStyleHorizontal"水平进度条 案例 进度条加载

探索TXE、TC、RXNE标志位在串口通信中的轮询与中断应用

浅谈一下STM32串口中断之TXE,TC,RXNE标志位 之前做一个项目&#xff0c;用到了串口中断&#xff0c;但是对TXE、TC和RXNE标志位的作用和使用方法不是很清楚&#xff0c;导致在调试过程中遇到了一些问题。通过查阅相关资料和实际操作&#xff0c;我对这三个标志位有了更深入的了…

Python酷库之旅-第三方库Pandas(010)

目录 一、用法精讲 22、pandas.read_hdf函数 22-1、语法 22-2、参数 22-3、功能 22-4、返回值 22-5、说明 22-6、用法 22-6-1、数据准备 22-6-2、代码示例 22-6-3、结果输出 23、pandas.HDFStore.put方法 23-1、语法 23-2、参数 23-3、功能 23-4、返回值 23-5…

【数据分析】Pandas_DataFrame读写详解:案例解析(第24天)

系列文章目录 一、 读写文件数据 二、df查询数据操作 三、df增加列操作 四、df删除行列操作 五、df数据去重操作 六、df数据修改操作 文章目录 系列文章目录前言一、 读写文件数据1.1 读写excel文件1.2 读写csv文件1.3 读写mysql数据库 二、df查询数据操作2.1 查询df子集基本方…

2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片

2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片 1 目标效果视频 CamManager 2 CamManager读取本地文件时序 3 BD_Vision_Utility添加代码 3.0 导入链接库 BD_OperatorSets.dllSystem.Windows.Forms.dllOpencvSharp 3.1 导入VisionParam中创建的文件Util_FileO…

乡村振兴指数与其30个原始变量数据(Shp/Dta/Excel格式,2000-2022年)

数据简介&#xff1a;这份数据是我国各地级市乡村振兴指数与其30各原始变量数据并对其进行地图可视化表达。城镇化是当今中国社会经济发展的必由之路。当前我国城镇化处于发展的关键时期&#xff0c;但城镇化发展的加快却是一把双刃剑&#xff0c;为何要如此形容呢?因为当前城…

【04】微服务通信组件Feign

1、项目中接口的调用方式 1.1 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 URLConnectio…

科研绘图系列:R语言径向柱状图(Radial Bar Chart)

介绍 径向柱状图(Radial Bar Chart),又称为雷达图或蜘蛛网图(Spider Chart),是一种在极坐标系中绘制的柱状图。这种图表的特点是将数据点沿着一个或多个从中心向外延伸的轴来展示,这些轴通常围绕着一个中心点均匀分布。 特点: 极坐标系统:数据点不是在直角坐标系中展…

AI时代还需要产品经理吗?需要什么样的?

在人工智能技术迅速发展的今天&#xff0c;我们不禁要思考&#xff0c;产品经理这个角色是否仍然重要&#xff1f;AI时代是否还需要他们&#xff1f; 很明确的说&#xff0c;需要&#xff01;为什么呢&#xff1f; 首先&#xff0c;我们必须认识到&#xff0c;AI虽然具有强大…

如何理解李彦宏说的“不要卷模型,要卷应用”

如何理解李彦宏说的“不要卷模型&#xff0c;要卷应用” “大家不要卷模型&#xff0c;要卷应用”这句话的意思是&#xff0c;呼吁行业不要把过多的精力和资源投入到模型的研发竞争中&#xff0c;而是应该更加注重基于模型的应用开发。 李彦宏提出这一观点的原因主要有以下几点…

容联云发布容犀大模型应用,重塑企业“营销服”|WAIC 2024

7月6日&#xff0c;在2024世界人工智能大会上&#xff0c;容联云成功举办主题为“数智聚合 产业向上”的生成式应用与大模型商业化实践论坛。 论坛上&#xff0c;容联云发布了容犀智能大模型应用升级&#xff0c;该系列应用包括容犀Agent Copilot、容犀Knowledge Copilot、容犀…

PHP星座微信小程序系统源码

&#x1f31f;每日星运&#xff0c;尽在掌握&#xff01;星座微信小程序&#xff0c;你的专属星空指南✨ &#x1f308; 一、每日运势&#xff0c;精准推送 想知道今天的你运势如何&#xff1f;星座微信小程序来告诉你&#xff01;&#x1f52e; 每天醒来&#xff0c;打开小程…

排座椅【详细代码题解】

[NOIP2008 普及组] 排座椅 题目描述 上课的时候总会有一些同学和前后左右的人交头接耳&#xff0c;这是令小学班主任十分头疼的一件事情。不过&#xff0c;班主任小雪发现了一些有趣的现象&#xff0c;当同学们的座次确定下来之后&#xff0c;只有有限的 D D D 对同学上课时…

(二)前端javascript中的数据结构之栈

栈是一种遵从后进先出&#xff08;LIFO&#xff09;原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端&#xff0c;称作栈顶&#xff0c;另一端就叫栈底。在栈里&#xff0c;新元素都靠近栈顶&#xff0c;旧元素都接近栈底。 栈是限定仅在表的一端进行插入和删除操作…

CnosDB:深入理解时序数据修复函数

CnosDB是一个专注于时序数据处理的数据库。CnosDB针对时序数据的特点设计并实现了三个强大的数据修复函数&#xff1a; timestamp_repair – 对时间戳列进行有效修复&#xff0c;支持插入、删除、不变等操作。value_repair – 对值列进行智能修复&#xff0c;根据时间戳间隔和…

【学习笔记】网络设备(华为交换机)基础知识2——常用设备管理命令

一、前期准备 提示&#xff1a;下面所有学习内容都是基于以下条件完成的 条件1.已经可以正常访问交换机的命令行接口 Console口本地访问教程参考 ① &#xff1a;使用第三方工具&#xff08;secureCRT软件&#xff09;通过console口本地访问访问交换机的详细操作过程 Telnet访…

静态路由配置注意事项及黑洞路由的使用

静态路由 1 . 定义 从管理员处学习到的数据转发路径&#xff0c;就称为静态路由。 2 . 路由表 Proto &#xff1a;协议&#xff08; Protocol &#xff09; Direct — 直连链路Static — 静态路由RIP 、OSPF 等 — 动态路由 Pre : 优先级&#xff08; Preference &#x…