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

文章目录

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

动态链接库和静态链接库

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

以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,一经查实,立即删除!

相关文章

工作中用到的数通、安全的查询、工具、文档链接

文章目录 一、华为1.设备信息查询华为序列号查询华为设备信息速查 2.维护华为交换机命名规则查看光模块信息交换机ping参数大全 3.实用文档智能升级堆叠重启指定成员设备堆叠主备倒换策略路由实现多出口重定向下一跳vrf与vrf、vrf与public互访路由配置总结 二、奇安信1.授权申请…

四十五----组件库设计

组件库设计主要考虑几点。 有意义: 命名准确,充分表意。参数准确,必要的类型检查。适当的注释 通用性:不要耦合特殊的业务功能。不要包含特定的代码处理逻辑。 ⽆状态,⽆副作⽤:状态向上层提取,尽量少⽤内部状态。解耦IO操作。 避免过度封装:合理冗余。避免过度抽象。 …

Rust 学习

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

LintCode 123 · Word Search (DFS字符处理经典题!)

123 Word Search Algorithms Medium Description Given a 2D board and a string word, find if the string word exists in the grid. The string word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally o…

arcgis api for js4.x 图层要素的增删改---使用服务地址的/applyEdits直接进行删除

添加新要素到图层 _addGeo(){cosnt self thislet url https://......./featurelayer/某某某图层/3let geo 你新绘制的图形let attributes 你新绘制图形的属性信息let addingGraphics Graphic({geometry:geo,attributes:attributes})const pro self._addToLayer(url , JS…

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>功能简…

如何设定一个N层CNN的Layer,CNN初始化

如何设定一个N层CNN的Layer&#xff0c;CNN初始化 前言干货代码解释 结语 前言 目前人工智能已经融入到我们的生活&#xff0c;大数据模型也是层出不穷。那我们就学习一些简单的模型设置。 干货 代码 # This is the original CNN layer setup, def build_cnn(input_layer):…

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[] …

Java与.Net的区别

Java 和 .NET 是两个不同的软件开发平台&#xff0c;它们在语言、生态系统、跨平台性和开发工具等方面有着不同的特点。 1. 语言&#xff1a;Java 使用 Java 编程语言&#xff0c;而 .NET 使用 C#、VB.NET、F# 等多种编程语言。Java 是一种面向对象的编程语言&#xff0c;它强…

在gen_server使用ets实例演示

Erlang的ETS&#xff08;Erlang term storage&#xff09;是一种在内存中存储数据的结构&#xff0c;类似于其他语言中的数据库。它允许你在Erlang程序中存储和检索数据。gen_server是Erlang中用于创建服务器的一种模式&#xff0c;它能够处理并发的客户端请求。 以下是在gen_…

大数据技术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…