静态链接库和动态链接库(隐式载入显式载入)

文章目录

  • 动态链接库和静态链接库
    • 什么是链接库?
    • 静态链接库
    • 动态链接库
    • 动态链接库的俩种链接方式
      • 加载时动态链接
      • 运行时动态链接

动态链接库和静态链接库

动态链接库和静态链接库都是共享代码的方法,只是二者略有区别。

以C/C++为例,一个可执行文件的生成主要包括预编译、编译、汇编和链接。而静态链接和动态链接就是 在链接阶段的俩种处理。
在这里插入图片描述

什么是链接库?

关于代码复用,有些文件专门用于存储可以重复使用的代码块,例如功能实用的函数或者类,我们通常将它们称为库文件,简称“库”(Library)。将这种库文件进行打包编译后得到二进制文件就是链接库。

链接库是一个不能独立运行的二进制文件,它必须经过其他程序调用,才可以载入内存中。

根据链接方式的不同,可以分为静态链接库动态链接库

静态链接库

所谓静态链接,就是在程序执行前,将所有目标文件同静态链接库一起组织成可执行文件,这样生成的可执行文件可以独立运行

采用静态链接库的方式共享代码有一个明显的缺点,那就是文件的体积会很大,因为可执行文件包含了所有目标文件和静态链接库的数据。这样容易造成内存空间的浪费。同时,不利用代码的模块化:如果有某个模块需要更新,整个程序都需要重新连接才能运行。

若是有多个程序调用相同函数,内存中就会存在这个函数的多个拷贝。

动态链接库

动态链接是相对静态链接而言的,动态链接所调用的代码并没有被打包到可执行文件中,被拷贝的往往只是某些函数的描述信息(如重定位信息),只有当程序执行的过程中,需要调用到动态库中的函数式,动态链接库中的函数才会被载入内存中。

一般情况下,一个程序如果使用了动态链接库,系统会保证内存中只有一份DLL的复制品。

动态链接库可以随可执行文件一同载入内存,也可以在可执行文件运行过程中载入,即可执行文件什么时候需要,动态链接库才会载入内存。

采用动态链接库方便程序的更新,当程序的某个模块更新后,只需要将旧的模块替换掉,程序运行时会自动将所有模板载入内存并动态地链接在一起。

但是动态链接库也有一定的缺点,静态链接生成的可执行文件能够在其他同类操作系统上直接运行。但是如果是动态链接生成的文件,在移植到其他操作系统上后,需要连同该可执行文件所调用到的DLL文件一并拷贝过去,不然不能保证程序的正常运行。

动态链接库的俩种链接方式

动态链接实际上还有俩种不同的连接方式:加载时动态链接和运行时动态链接(隐式加载显式加载

加载时动态链接

在加载时动态链接中,应用程序像本地函数一样显式调用导出的 DLL 函数。要使用加载时动态链接,请在编译和链接应用程序时提供头文件 (.h) 和导入库 (.lib) 文件。执行此操作时,链接器将为系统提供加载 DLL 所需的信息,并在加载时解析导出的 DLL 函数位置。

使用加载时动态链接,同静态链接有一个相同的缺点,那就是如果程序的体积稍大,程序开始时加载的时间就会过长。

加载时动态链接和静态链接的区别:

  • 链接的时机:加载时动态链接是在程序加载时程序才会将动态库载入到内存中,而静态链接则是在编译的时候就已经将静态库的代码和数据嵌入到可执行文件中了。

正如上面所说的,使用加载时动态链接,需要提供头文件 (.h) 和导入库 (.lib) 文件。可以直接在源码中引入.lib文件。

例如:

#pragma comment(lib, "dllDemo.lib")

为了更好的模块化设计,也可以将lib中所要用到函数声明放在头文件中。

例如:

//dllDemo.h
#ifndef _DLLDEMO_H
#DEFINE _DLLDEMO_H#pragma comment(lib,"dllDemo.lib")
_declspec(dllexport) int add(int, int);
_declspec(dllexport) int sub(int, int);#endif

之后的主程序中记得

#include "dllDemo.h"

上述代码还用了_declspec(dllimport) 标识符声明函数来自动态链接库。

运行时动态链接

在运行时动态链接中,应用程序调用LoadLibrary 函数或LoadLibraryEx 函数在运行时加载DLL。 DLL成功加载后,可以使用GetProcAddress函数获取要调用的导出DLL函数的地址。当您使用运行时动态链接时,不需要导入库文件。

LoadLibrary 函数的作用是将指定的模块加载到调用进程的地址空间中。

函数定义:

HMODULE LoadLibraryA([in] LPCSTR lpLibFileName //模块的名称。这可以是库模块(.dll 文件)也可以是可执行模块(.exe文件)
);

如果调用成功,将会返回该模块的句柄。

当得到该模块的句柄后,可以使用GetProcAddress函数,它从指定的动态链接库 (DLL) 检索导出函数(也称为过程)或变量的地址。

函数原型:

FARPROC GetProcAddress([in] HMODULE hModule, //该模块的句柄[in] LPCSTR  lpProcName  //函数或变量的名称
);

如果调用成功,则返回导出函数或变量的地址。

示例:

#include <windows.h>int main() {// 加载动态链接库HMODULE hLibrary = LoadLibrary("example.dll");if (hLibrary != NULL) {// 获取函数地址FARPROC functionAddress = GetProcAddress(hLibrary, "exampleFunction");if (functionAddress != NULL) {// 调用动态链接库中的函数typedef void (*FunctionType)();FunctionType myFunction = (FunctionType)functionAddress;myFunction();}// 卸载动态链接库FreeLibrary(hLibrary);}return 0;
}

以上关于运行时动态链接的实例是基于Windows的,如果是在linux上使用运行时动态链接,则需要通过使用 dlopendlsym以及 dlclose函数。

实例:

#include <dlfcn.h>int main() {// 加载动态链接库void* libraryHandle = dlopen("libexample.so", RTLD_LAZY);if (libraryHandle != NULL) {// 获取函数地址void (*myFunction)() = (void (*)())dlsym(libraryHandle, "exampleFunction");if (myFunction != NULL) {// 调用动态链接库中的函数myFunction();}// 卸载动态链接库dlclose(libraryHandle);}return 0;
}
参考
https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library
https://c.biancheng.net/dll/what_is_library.html
https://blog.csdn.net/fuzhongmin05/article/details/54616520
https://blog.csdn.net/u010154760/article/details/45689899?spm=1001.2014.3001.5502

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

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

相关文章

Rust 学习

Rust 官网&#xff1a;https://www.rust-lang.org/zh-CN/ 1、Rust 简介 Rust 是一门注重安全&#xff08;safety&#xff09;、速度&#xff08;speed&#xff09;和并发&#xff08;concurrency&#xff09;的现代系统编程语言。Rust 通过内存安全来实现以上目标&#xff0c;但…

Day57力扣打卡

打卡记录 最小体力消耗路径 链接 Dijkstra 将Dijkstra算法从计算最短路径转化为计算路径最大差值。 class Solution:def minimumEffortPath(self, heights: List[List[int]]) -> int:n, m len(heights), len(heights[0])dist [0] [0x3f3f3f3f] * (n * m - 1)vis set…

iPhone 数据恢复:iMyFone D-Back iOS

iMyFone D-Back iOS 最佳 iPhone 数据恢复&#xff0c;最好的 iPhone 数据恢复软件&#xff0c;恢复成功率最高。 直接从iOS设备、iTunes/iCloud/第三方程序备份快速恢复数据。 有选择地恢复已删除的照片、WhatsApp、消息和 18 多种其他数据类型。 仅通过 iCloud 帐户访问即可从…

关系型数据库-SQLite介绍

优点&#xff1a; 1>sqlite占用的内存和cpu资源较少 2>源代码开源&#xff0c;完全免费 3>检索速度上十几兆、几十兆的数据库sqlite很快&#xff0c;但是上G的时候最慢 4>管理简单&#xff0c;几乎无需管理。灵巧、快速和可靠性高 5>功能简…

Vue router深入学习

Vue router深入学习 一、单页应用程序介绍 1.概念 单页应用程序&#xff1a;SPA【Single Page Application】是指所有的功能都在一个html页面上实现 2.具体示例 单页应用网站&#xff1a; 网易云音乐 https://music.163.com/ 多页应用网站&#xff1a;京东 https://jd.co…

springboot打成war包及VUE打成war包放入tomcat启动

1.springboot打成war包步骤 首先在springboot启动类中继承SpringBootServletInitializer&#xff0c;重写configure方法&#xff0c;如下: SpringBootApplication() public class StartApplication extends SpringBootServletInitializer {public static void main(String[] …

大数据技术10:Flink从入门到精通

导语&#xff1a;前期入门Flink时&#xff0c;可以直接编写通过idea编写Flink程序&#xff0c;然后直接运行main方法&#xff0c;无需搭建环境。我碰到许多初次接触Flink的同学&#xff0c;被各种环境搭建、提交作业、复杂概念给劝退了。前期最好的入门方式就是直接上手写代码&…

[渗透测试学习] CozyHosting - HackTheBox

文章目录 信息搜集 信息搜集 nmap扫描一下&#xff0c;发现存在80端口和22端口 nmap -sV -sC -p- -v --min-rate 1000 10.10.11.230直接访问80端口发现有跳转 那么我们将ip添加到hosts里面&#xff0c;成功访问 观察发现是企业网站&#xff0c;扫描一下没有子域名 那么就扫…

【后端学前端】第二天 css动画 动感菜单(css变量、过渡动画、过渡延迟、js动态切换菜单)

目录 1、学习信息 2、源码 3、变量 1.1 定义变量 1.2 使用变量 1.3 calc() 函数 4、定位absolute和fixed 5、transform 和 transition&#xff0c;动画 5.1 变形transform 5.2 transition 5.3 动画animation 6、todo 1、学习信息 视频地址&#xff1a;css动画 动感菜…

【jenkins操作步骤】

一、安装ant 1、下载安装文件 1.1 进入https://ant.apache.org/ 然后点击 https://ant.apache.org/bindownload.cgi 超连接下载即可 1.2下载到本地&#xff0c;最好放到D盘下&#xff0c;然后把apache-jmeter-4.0\extras目录下的ant-jmeter-1.1.1.jar 文件放置到ant下的lib目…

Java最全面试题专题---2、Java集合容器(1)

集合容器概述 什么是集合 **集合框架&#xff1a;**用于存储数据的容器。 集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。 任何集合框架都包含三大块内容&#xff1a;对外的接口、接口的实现和对集合运算的算法。 **接口&#xff1a;**表示集合的抽象数据类…

开箱即用的C++决策树简单实现

一个数据结构期末作业&#xff08;有兴趣用的话可以高抬贵手star下⭐~&#xff09;GitHub - mcxiaoxiao/c-Decision-tree: 决策树c简单实现 &#x1f333; c-Decision-tree 附大作业/课设参考文档.doc &#x1f333; c-Decision-tree Introduction &#x1f64c; c-Decision…

[c++]—vector类___基础版(带你了解vector熟练掌握运用)

&#x1f469;&#x1f3fb;‍&#x1f4bb;作者:chlorine 目录 &#x1f393;标准库类型vector &#x1f393;定义和初始化vector的对象 &#x1f4bb;列表初始化vector对象 &#x1f4bb;创建指定数量的元素 &#x1f576;️值初始化 ❗列表初始化还是值初始化&#xf…

树莓派,opencv,Picamera2利用舵机云台追踪特定颜色对象

一、需要准备的硬件 Raspiberry 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目标…

智慧机房与3D机房动环监控系统的应用

智慧机房是什么&#xff1f; 智慧机房是集采集信息、实时监控、数据分析、统一管理、故障告警等功能于一体的全方位、立体化的智能环境监控系统&#xff0c;构建物联网、大数据和云计算背景下现代企业的“数据心脏”。它能为机房管理者呈现细致入微的关键性数据&#xff0c;优…

电子学会C/C++编程等级考试2022年06月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:逃离迷宫 你在一个地下迷宫中找到了宝藏,但是也触发了迷宫机关,导致迷宫将在T分钟后坍塌,为此你需要在T分钟内逃离迷宫,你想知道你能不能逃离迷宫。迷宫是一个边长为m的正方形,其中"S"表示你所在的位置,"…

<url-pattern>/</url-pattern>与<url-pattern>/*</url-pattern>的区别

<url-pattern>/</url-pattern> servlet的url-pattern设置为/时&#xff0c; 它仅替换servlet容器的默认内置servlet&#xff0c;用于处理所有与其他注册的servlet不匹配的请求。直白点说就是&#xff0c;所有静态资源&#xff08;js&#xff0c;css&#xff0c;ima…

HCIA-H12-811题目解析(9)

1、【单选题】下面选项中&#xff0c;能使一台IP地址为10.0.0.1的主机访问Interne的必要技术是&#xff1f; 2、【单选题】 FTP协议控制平面使用的端口号为&#xff1f; 3、【单选题】 使用FTP进行文件传输时&#xff0c;会建立多少个TCP连接&#xff1f; 4、【单选题】完成…

做数据分析为何要学统计学(10)——如何进行时间序列分析

时间序列是由随时间变化的值构成&#xff0c;如产品销量、气温数据等等。通过对时间序列展开分析&#xff0c;能够回答如下问题&#xff1a; &#xff08;1&#xff09;被研究对象的活动特征是否有周期性&#xff08;也称季节性&#xff09;&#xff08;2&#xff09;被研究对…

UE4/UE5 修改/还原场景所有Actor的材质

使用蓝图方法&#xff1a; 1.修改场景所有Actor 材质&#xff1a; Wirframe&#xff1a;一个材质类 MatList&#xff1a;获取到的所有模型的全部材质 的列表 TempAllClass&#xff1a;场景中所有获取的 Actor 的列表 功能方法如下&#xff1a; 蓝图代码可复制在&#xff1a…