显式链接和隐式链接

2024-09-04 16:12
文章标签 链接 隐式 显式

本文主要是介绍显式链接和隐式链接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        显式链接(Explicit Linking)和隐式链接(Implicit Linking)是两种动态链接库(dll/so)的使用方式,它们在程序与动态库之间的交互方式上存在显著差异。    

显式链接(Explicit Linking)

定义与特点

        显式链接是指在程序运行时,由程序代码主动加载动态链接库到进程的地址空间中。这种方式允许程序在需要时才加载特定的库,从而增加了程序的灵活性和可控性。

        显式链接通常通过调用系统提供的API函数(如Windows下的LoadLibrary或Linux下的dlopen)来实现,这些函数会加载指定的dll/so文件,并返回一个句柄或指针,用于后续的函数调用。通过GetProcAddress(Windows)或dlsym(Linux)等函数,程序可以获取dll/so中导出函数的地址,并通过函数指针进行调用。

应用场景

  • 插件系统:允许程序在运行时加载不同的插件,实现功能的扩展和定制。
  • 可选功能:某些功能可能不是必需的,可以在用户需要时通过显式链接加载相应的dll/so。
  • 跨平台兼容:通过条件编译和显式链接,可以实现跨平台的代码复用和部署。

隐式链接(Implicit Linking)

定义与特点

        隐式链接是最为常见的,所有的编译环境默认都是采用隐式链接的方式使用动态库。隐式链接会在链接生成可执行程序时就确立依赖关系,在该程序启动时,操作系统自动会检查它依赖的动态库, 并一一加载到该程序的内存空间,程序员就不需要操心什么时候加载动态库了。 

        隐式链接的实现通常涉及到包含动态库的头文件(.h)和链接动态库。在编译时,编译器会使用这些文件来解析对动态库中函数的引用,并在链接阶段将相关信息嵌入到可执行文件中【1】。

【1】链接动态库,是在编译阶段链接器将库的头文件和库等信息嵌入到可执行程序中。如:

# -lcgicc: 指示链接器在构建可执行文件或库时,要链接到名为 libcgicc 的动态库或静态库。
# 这里的 lib 前缀和 .so(对于动态库)或 .a(对于静态库)后缀在命令行中通常是省略的
arm-linux-gnueabihf-g++ -o myapp myapp.cpp -lcgicc

        当程序运行时,操作系统会根据可执行文件中的信息自动查找并加载所需的动态库文件。如果找不到动态库文件或者库文件中的函数与可执行文件中的引用不匹配,程序将无法正常运行。

应用场景

  • 大多数桌面应用程序:这些应用程序通常依赖多个动态库来提供丰富的功能和用户界面。隐式链接可以简化开发过程并降低维护成本。
  • 标准库和框架:如C++标准库、.NET框架等系统级或应用级框架通常通过隐式链接的方式提供给开发者使用。

显式链接优缺点

优点

  • 灵活性高:显式链接允许程序在运行时根据需要动态地加载和卸载dll/so(动态链接库),这提供了高度的灵活性。程序可以根据用户的操作、系统状态或其他条件来决定是否加载某个dll/so,从而优化资源使用。
  • 错误处理能力强:在显式链接中,如果dll/so文件不存在、损坏或版本不兼容,程序可以捕获这些错误并作出相应的处理,如显示错误消息、尝试加载其他版本的dll/so或回退到不使用该dll/so的功能。
  • 减少启动时间:由于dll/so是在程序运行时根据需要加载的,因此可以减少程序启动时的加载时间。这对于包含大量可选功能的大型应用程序尤其有用。
  • 支持插件机制:显式链接是实现插件机制的基础。通过动态加载插件dll/so,程序可以在不修改自身代码的情况下扩展新功能。

缺点

  • 编程复杂度增加:显式链接需要程序员在代码中显式地处理dll/so的加载、函数地址的获取和错误处理等问题,这增加了编程的复杂度。
  • 性能开销:每次加载和卸载dll/so时,操作系统都需要执行一系列操作来管理内存和文件资源,这可能会引入一定的性能开销。
  • 依赖管理复杂:显式链接的程序需要显式地指定dll/so的路径和名称,这增加了依赖管理的复杂性。如果dll/so的路径或名称发生变化,程序可能无法正确加载dll/so。

隐式链接优缺点

优点

  • 使用简单:隐式链接通过链接器将dll/so的导入信息嵌入到可执行文件中,并在程序启动时由操作系统自动加载所需的dll/so。这使得程序员无需在代码中显式地处理dll/so的加载和函数地址的获取等问题。
  • 依赖管理相对简单:由于dll/so的导入信息被嵌入到可执行文件中,因此操作系统可以根据这些信息自动查找和加载dll/so,这简化了依赖管理。
  • 性能开销较小:由于dll/so是在程序启动时由操作系统自动加载的,因此与显式链接相比,隐式链接在加载dll/so时的性能开销可能较小。

缺点

  • 灵活性较低:隐式链接的程序在启动时会自动加载所有依赖的dll/so,这限制了程序的灵活性。如果某个dll/so不是必需的,但在程序启动时被加载了,那么就会浪费内存和其他系统资源。
  • 错误处理能力较弱:在隐式链接中,如果dll/so文件不存在、损坏或版本不兼容,程序可能会立即崩溃或显示错误消息,而无法像显式链接那样进行错误处理。
  • 启动时间可能较长:如果程序依赖多个dll/so,并且这些dll/so在程序启动时都被加载了,那么程序的启动时间可能会相对较长。

实例:隐式链接

一般我们在使用某个库时的步骤:C++实现web后台 cgi 程序时,需要使用 libcgicc.so 动态库。

1)将动态库拷贝至/lib/下

2) 代码中包含要使用的库函数所对应的头文件

库的编译阶段:

1)使用-l来链接动态库:-lcgicc

2)-I 来指定库的头文件

arm-linux-gnueabihf-g++ -o myapp.cgi myapp.cpp -I /usr/local/cgicc-3.2.20/include -lcgicc

注意:  在代码中包含库头文件时,要和编译指定的库头文件路径相匹配。

这篇关于显式链接和隐式链接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136413

相关文章

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

短链接算法原理

平时我们在上网的时候,印象最深刻的有一次是短链接的服务。例如:平时在微信上看一个网页的时候,如果我们选择在浏览器打开的时候,会看到很长的URL,我们分享的时候,会看到一个很短URL,这就是本次所说的短链接的应用之一。 长链接示例:https://mp.weixin.qq.com/s?__biz=MzAxNzMwOTQ0NA==&mid=2653355437&idx=1&sn=5901826ea63

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl

编译和链接那点事下

http://www.0xffffff.org/?p=357 上回书我们说到了链接以前,今天我们来研究最后的链接问题。         链接这个话题延伸之后完全可以跑到九霄云外去,为了避免本文牵扯到过多的话题导致言之泛泛,我们先设定本文涉及的范围。我们今天讨论只链接进行的大致步骤及其规则、静态链接库与动态链接库的创建和使用这两大块的问题。至于可执行文件的加载、可执行文件的运行时

编译和链接那点事上

http://www.0xffffff.org/?p=323  有位学弟想让我说说编译和链接的简单过程,我觉得几句话简单说的话也没什么意思,索性写篇博文稍微详细的解释一下吧。其实详细的流程在经典的《Linkers and Loaders》和《深入理解计算机系统》中均有描述,也有国产的诸如《程序员的自我修养——链接、装载与库》等大牛著作。不过,我想大家恐怕很难有足够的时间去研读这些厚如

【JVM】JVM栈帧中的动态链接 与 Java的面向对象特性--多态

栈帧 每一次方法调用都会有一个对应的栈帧被压入栈(虚拟机栈)中,每一个方法调用结束后,都会有一个栈帧被弹出。 每个栈帧中包括:局部变量表、操作数栈、动态链接、方法返回地址。 JavaGuide:Java内存区域详解(重点) 动态链接 动态链接:指向运行时常量池中该栈帧所属方法的引用。 多态 多态允许不同类的对象对同一消息做出响应,但表现出不同的行为(即方法的多样性)。 多态

selenium的webdriver三种等待方式(显式等待WebDriverWait+implicitly_wait隐式等待+sleep强制等待)

隐式等待是等页面加载,不是等元素!!! 1、显式等待  一个显式等待是你定义的一段代码,用于等待某个条件发生然后再继续执行后续代码。显式等待是等元素加载!!! from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import

C++隐式转换

文章目录 一、基本类型转换1.1 整型提升(Integer Promotion)1.2 算术转换(Arithmetic Conversion) 二、类类型的隐式转换2.1 通过单参数构造函数进行隐式转换2.2 通过转换函数进行隐式转换 三、隐式类型转换的注意事项3.1 防止不必要的隐式转换3.2 隐式类型转换的优先级 四、总结 视频教学笔记1、隐形构造函数案例1案例2 2、explicit使