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

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

链接器的工作原理

链接器(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.mzph.cn/diannao/42864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20240704每日后端------聊聊 mybatis的 where 1=1

目标 最近&#xff0c;在项目中使用MyBatis进行SQL脚本编写时&#xff0c;我遇到了以“WHERE 11”开头的WHERE子句的做法&#xff0c;以简化多个条件的串联。这里有一个例子来讨论这种技术以及“WHERE 11”是否对性能有任何影响。 <select id"" parameterType&q…

【数据结构】09.树与二叉树

一、树的概念与结构 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 根结点&#xff1a;根…

04采访:数字人直播

​AI技术的迭代对数字人直播一定是有正向推动作用的。直播可持续性差,投入产出极不协调。不适合前期大量投入。直播现在这个东西有一个问题,因为直播开始带货了,就已经不是一个单纯的娱乐性质的视频内容,而是对带有一种商业目的内容。 直播带货的痛点:对主播而言是观众;…

俯卧撑计数器(Python)

通过 MediaPipe 检测人体姿态&#xff0c;计算俯卧撑角度和计数&#xff0c;并在图像上进行可视化展示 需要有cv2库和mediapipe库 mediapipe库&#xff1a; MediaPipe是Google开源的机器学习框架&#xff0c;用于构建实时音频、视频和多媒体处理应用程序。它提供了一组预训练的…

一文清晰了解HTML

有这样一个txt记事本文件和一张图片&#xff1a; txt文本内容是这样的&#xff1a; <html><head><title>HTML学习</title></head><body><h1>hello HTML</h1><img src"高清修复.png"/></body> </html…

LabVIEW的JKI State Machine

JKI State Machine是一种广泛使用的LabVIEW架构&#xff0c;由JKI公司开发。这种状态机架构在LabVIEW中提供了灵活、可扩展和高效的编程模式&#xff0c;适用于各种复杂的应用场景。JKI State Machine通过状态的定义和切换&#xff0c;实现了程序逻辑的清晰组织和管理&#xff…

VSCode工程中task.json的作用

在 Visual Studio Code&#xff08;VSCode&#xff09;中&#xff0c;tasks.json 文件是用来定义和配置任务&#xff08;Tasks&#xff09;的。任务指的是在开发过程中需要自动化执行的一系列操作&#xff0c;例如编译代码、运行测试、打包项目等。通过配置 tasks.json&#xf…

In Search of Lost Online Test-time Adaptation: A Survey--论文笔记

论文笔记 资料 1.代码地址 https://github.com/jo-wang/otta_vit_survey 2.论文地址 https://arxiv.org/abs/2310.20199 3.数据集地址 1论文摘要的翻译 本文介绍了在线测试时间适应(online test-time adaptation,OTTA)的全面调查&#xff0c;OTTA是一种专注于使机器学习…

【软件分享】我们都需要会用的ArcGIS10.8和ArcGIS Pro

ArcGIS是地理人必备的地理制图、空间分析常用的工具&#xff0c;读地理&#xff0c;或多或少都会接触到ArcGIS的使用&#xff0c;今天小编要带来的就是ArcGIS10.8软件资源和升级版ArcGIS Pro的软件资源。 软件安装包获取 公众号回复关键词&#xff1a;“ArcGIS"&#xff…

*算法训练(leetcode)第二十五天 | 134. 加油站、135. 分发糖果、860. 柠檬水找零、406. 根据身高重建队列

刷题记录 134. 加油站135. 分发糖果860. 柠檬水找零406. 根据身高重建队列 134. 加油站 leetcode题目地址 记录全局剩余油量和当前剩余油量&#xff0c;当前剩余小于0时&#xff0c;其实位置是当前位置的后一个位置。若全局剩余油量为负&#xff0c;则说明整体油量不足以走完…

防爆手机终端安全管理平台

防爆手机终端安全管理平台能够满足国家能源、化工企业对安全生产信息化运行需求&#xff0c;能够快速搭建起高效、快捷的移动终端管理平台&#xff0c;提高企业安全生产管理水平&#xff0c;保证企业的安全运行和可持续发展。#防爆手机 #终端安全 #移动安全 能源、化工等生产单…

公有链、私有链与联盟链:区块链技术的多元化应用与比较

引言 区块链技术自2008年比特币白皮书发布以来&#xff0c;迅速发展成为一项具有颠覆性潜力的技术。区块链通过去中心化、不可篡改和透明的方式&#xff0c;提供了一种全新的数据存储和管理方式。起初&#xff0c;区块链主要应用于加密货币&#xff0c;如比特币和以太坊。然而&…

SQL Server 设置端口详解

前言 在数据库管理和开发过程中&#xff0c;SQL Server是一个广泛使用的关系型数据库管理系统。默认情况下&#xff0c;SQL Server使用1433端口进行通信。然而&#xff0c;出于安全性、端口冲突或网络限制等原因&#xff0c;我们有时需要更改SQL Server的默认端口。本文将详细…

VBA-计时器的数据进行整理

对计时器的数据进行整理 需求原始数据程序步骤VBA程序结果 需求 需要在txt文件中提取出分和秒分别在两列 原始数据 数据结构 计次7 00:01.855 计次6 00:09.028 计次5 00:08.586 计次4 00:08.865 计次3 00:07.371 计次2 00:06.192 计次1 00:05.949 程序步骤 1、利用Trim()去…

易备数据备份软件——低成本、高效能、全方位地守护您的数据安全

在数字化的时代&#xff0c;数据是企业和个人最宝贵的资产。然而&#xff0c;数据丢失、系统故障、恶意攻击等威胁时刻存在。如何确保数据的安全与完整&#xff1f;易备数据备份软件为您提供全方位无死角的解决方案&#xff0c;让您高枕无忧&#xff01; 云备份&#xff1a;畅…

CV每日论文--2024.7.4

1、InternLM-XComposer-2.5: A Versatile Large Vision Language Model Supporting Long-Contextual Input and Output 中文标题&#xff1a;InternLM-XComposer-2.5&#xff1a;支持长上下文输入和输出的多功能大视觉语言模型 简介&#xff1a;我们推出了InternLM-XComposer-…

079、类的继承

继承是对已有的类进行扩展创建出新的类&#xff0c;这个过程就叫做继承。其中&#xff0c;提供继承信息的类叫做父类&#xff08;超类、基类&#xff09;&#xff0c;得到继承信息的类称为子类&#xff08;派生类&#xff09;。 基本语法 继承是通过在类定义语句中使用圆括号…

控制周期与控制频率

控制周期是指控制系统中执行一次完整控制循环所需的时间间隔。它表示了控制系统对输入信号进行处理、执行控制算法、生成输出信号并更新系统状态的频率。在实时控制系统中&#xff0c;控制周期的选择对系统的性能和稳定性具有重要影响。较短的控制周期可以提高系统的响应速度&a…

高级java每日一道面试题-2024年7月8日

文章目录 面试官问: final 在java中有什么作用面试者回答:1. final修饰变量基本数据类型&#xff1a;示例&#xff1a; 对象引用&#xff1a;示例&#xff1a; 2. final修饰方法示例&#xff1a; 3. final修饰类示例&#xff1a; 4. final局部变量和参数示例&#xff1a; 总结 …

互联网十万个为什么之什么是CDN?

CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是一组分布在不同地理位置的服务器&#xff0c;其目的是更有效地向用户分发互联网内容。通过缓存内容&#xff08;如网页、图片、视频和其他类型的网络数据&#xff09;在多个服务器上&#xff0c…