当前位置: 首页 > news >正文

SDK之动态链接库开发—基本概念

动态链接库(Dynamic Link Library,简称 DLL)是一种在运行时加载的库,可用于在多个应用程序之间共享代码和数据。与静态链接库相比,动态链接库的主要优劣势如下:

优势:

  • 空间效率更高,因为库代码和数据不需要在每个应用程序中都有一份副本;
  • 更新和维护更容易,因为库的所有应用程序都会受益于更新,而无需重新编译每个应用程序;
  • 可以通过更新动态链接库的版本来解决库中的错误或安全漏洞,而不必重新编译每个应用程序。

劣势:

  • 运行时加载可能会导致性能损失;
  • 库的版本控制可能会变得复杂,因为多个应用程序可能需要不同版本的库;
  • 库的依赖关系可能会变得复杂,因为库本身可能依赖于其他库。

以下是一些动态链接库开发的基本步骤:

  1. 编写代码:编写您想要共享的代码和数据,将其放入一个或多个源文件中。

  2. 编译代码:使用适当的编译器和选项将源代码编译为共享对象文件(.so 文件)或动态链接库文件(.dll 文件)。

  3. 链接代码:将库的对象文件链接到动态链接库文件中,以便它们可以在运行时加载。

  4. 测试库:编写一个或多个测试程序,以确保库可以正常工作并且在不同的应用程序中正确地共享。

  5. 安装库:将库文件和任何必需的头文件、文档和其他资源安装在系统中,以便其他开发人员可以使用它。

  6. 文档化库:为库编写文档,以便其他开发人员可以了解如何使用它以及如何与它交互。

总的来说,动态链接库是一种非常有用的工具,可以帮助开发人员在多个应用程序之间共享代码和数据,减少代码冗余,并提高开发效率。

1、静态链接库和动态链接库

用静态库的话,目标电脑上如果没有这个文件的话能正常使用程序;用动态库的话,目标电脑上必须要有这个文件才能正常使用程序,或者你可以要发布程序的时候将这个文件一起打包。

 

2、动态链接库的连接方式:隐式链接和显式加载

隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中,在链接时需要用到lib文件,才能直接通过DLL中导出的函数名来调用函数;显式加载则是在运行时加入,在代码中需要显式调用LoadLibrary()和FreeLibrary(),而且在调用dll中导出的函数时,需要使用GetProcAddress()获取想要引入的函数。

两种方式对于你的程序调用动态库时没有任何区别,只是你在编程时,步骤是不一样的:显式调用麻烦了点,但可以没有相应的lib库;隐式调用,使用起来比较简单,有函数的声明就可以了,但必须有lib库。

隐式加载默认是加载到内存中的,始终占用内存;显式加载,你加载时占用内存,释放了就不占用内存了。如果该DLL已经载入,loadlibrary只是会增加一个引用计数,相同,freelibrary也只是减少引用计数,如果引用计数为0时,DLL才从内存中移除。

显式和隐式只是对于代码编写时来说的,最后产生的可执行程序,不管是显式和隐式,都是用loadlibrary载入的。显式与隐式不是用在这些方面的,显式加载适合需要动态的选用DLL的情况。使用导出类和导出结构体的时候,隐式链接较为方便,而显式链接则很麻烦。

显式链接库的好处:在需要的时候加载动态链接库某个函数。

隐式链接的缺点:使用比较简单,在程序的其他部分可以任意使用函数,但是当程序访问十来个dll动态链接库的时候,此时如果都使用隐式链接的时候,启动此程序的时候,这十来个动态链接库都需要加载到内存,映射到内存的地址空间,这就会加大进程的启动时间,而且程序运行过程中,只是在某个条件下使用某个函数,如果使用隐式链接会造成资源的浪费。这样需要采用显式(动态加载)的方式。

3、def和extern"C"

如果DLL使用的是def文件,要删除TestDll.h文件中关键字extern"C"。

 

4、__declspec(dllimport)__declspec(dllexport)

不使用__declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用__declspec(dllimport) 才能导入 DLL 中使用的变量。

5、动态载入(显式链接)DLL需要的三个函数

(LoadLibrary,GetProcAddress,FreeLibrary)

动态载入(显式链接) DLL方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。

使用方法是:用LoadLibrary 函数加载动态链接库到内存,用GetProcAddress函数动态获得 DLL 函数的入口地址。当一个 DLL 文件用LoadLibrary 显式加载后,在任何时刻均可以通过调用FreeLibrary 函数显式地从内存中把它给卸载。

动态调用使用的Windows API 函数主要有 3 个, 分别是LoadLibrary、GetProcAddress 和FreeLibrary。

(1)LoadLibrary函数

注:Delphi中还提供了SafeLoadLibrary 函数,它封装了Loadlibrary 函数,可以装载由Filename 参数指定的WindowsDLL或Linux 共享对象。它简化了DLL的装载并且使装载更加安全。

[格式]:

functionLoadLibrary(LibFileName : PChar): Thandle;

[功能]:加载由参数LibFileName 指定的 DLL 文件。

[说明]:参数LibFileName 指定了要装载的 DLL 文件名,如果LibFileName 没有包含一个路径,系统将按照:当前目录、Windows目录、Windows系统目录、包含当前任务可执行文件的目录、列在 PATH环境变量中的目录等顺序查找文件。

如果函数操作成功,将返回装载 DLL 库模块的实例句柄,否则,将返回一个错误代码,错误代码的定义如下表所示。

错误代码

  含义

  0

  系统内存不够,可执行文件被破坏或调用非法

  2

  文件没有被发现

  3

  路径没有被发现

  5

  企图动态链接一个任务错误或者有一个共享或网络保护错误

  6

  库需要为每个任务建立分离的数据段  

  8

  没有足够的内存启动应用程序  

10

  Windows  版本不正确  

  11

  可执行文件非法或不是Windows  应用程序,或在.  EXE映像中有错误  

  12

  应用程序为一个不同的操作系统设计(如  OS/2  

  13

  应用程序为  MS  DOS   4. 0  设计  

  14

  可执行文件的类型不知道  

  15

  试图装载一个实模式应用程序(为早期Windows  版本设计)

  16

  试图装载包含可写的多个数据段的可执行文件的第二个实例  

  19

  试图装载一个压缩的可执行文件(文件必须被解压后才能被装载)  

  20

  DLL  文件非法

  21

  应用程序需要  32  位扩展

假如在应用程序中用 LoadLibrary 函数装入某一个 DLL 前,其他应用程序已把该 DLL 装入内存中了,则系统将不再装入该 DLL 的另一个实例,而是使该 DLL 引用计数 1

 

2GetProcAddress 函数

[格式]

function GetProcAddress(Module:Thandle;ProcName:PChar): TfarProc;

 

[功能]:返回参数 Module 指定的模块中,由参数 ProcName 指定的过程或函数的入口地址。

 

[说明]:参数 Module 包含被调用函数的 DLL 句柄,这个值由 LoadLibrary 返回, ProcName是指向含有函数名的以 nil 结尾的字符串指针,或者可以是函数的次序值,但大多数情况下,用函数名是一种更稳妥的选择。如果该函数执行成功,则返回 DLL 中由参数 ProcName 指定的过程或函数的入口地址,否则返回 nil

 

3FreeLibrary 函数

[格式]:

procedure  FreeLibrary(Module: Thandle);

[说明]:将由参数Module 指定的 DLL 文件从内存中卸载 1 次。

[说明]:Module为 DLL 库的句柄。这个值由LoadLibrary 返回。由于 DLL 在内存中只装载一次,因此调用FreeLibrary 首先使 DLL 的引用计数减 1,如果计数减为 0 则卸载该 DLL。

[注意]:每调用一次LoadLibrary 函数就应调用一次FreeLibrary 函数,以保证不会有多余的库模块在应用程序结束后仍留在内存中,否则导致内存泄漏

相关文章:

SDK之动态链接库开发—基本概念

动态链接库(Dynamic Link Library,简称 DLL)是一种在运行时加载的库,可用于在多个应用程序之间共享代码和数据。与静态链接库相比,动态链接库的主要优劣势如下: 优势: 空间效率更高&#xff0…...

spring生命周期、IOC工作流程、AOP过程,循环依赖、BeanFactory和FactoryBean

1、生命周期 划分为5个阶段: 创建前准备阶段、创建实例阶段、 依赖注入阶段、 容器缓存阶段、销毁实例阶段。一、创建前准备阶段:这个阶段主要的作用是,Bean 在开始加载之前,需要从上下文和相关配置中解 析并查找 Bean 有关的扩展…...

小黑子—Java从入门到入土过程:第六章

Java零基础入门6.0Java系列第六章1. 面向对象综合练习1.1 文字版格斗游戏参数占位,格式化输出回顾关于printf和print和println的区别1.2 对象数组练习1.2.1 练习一1.2.2 练习二1.2.3 练习三1.2.4 练习四1.3 键盘录入回顾1.4 复杂对象数组练习1.4.1 复杂练习一1.4.2 …...

python实战应用讲解-【numpy数组篇】常用函数(二)(附python示例代码)

目录 Python numpy.flipud() Python numpy.insert() Python numpy.ravel() Python numpy.shapes() Python numpy.roll() Python numpy.rot90() Python numpy.append() Python numpy.flipud() Python numpy.flipud()函数将数组(每列中的项)按上下方向翻转,但保留形状。…...

windows10 java 创建合约

a. 安装Nodejs 主要是方便使用npm 命令 并配置环境变量 b.使用 npm 可以便捷地安装Solidity编译器solcjs npm install -g solc c.找个目录 创建一个solidity文件 如 // SPDX-License-Identifier: GPL-3.0pragma solidity >0.8.2 <0.9.0;/*** title Storage* dev Store…...

阿里巴巴获得商品详情 API调用示例

为了进行此平台API的调用&#xff0c;首先我们需要做下面几件事情。 1、 获取一个KEY。 2、 参考API文档里的接入方式和示例。 3、查看测试工具是否有需要的接口&#xff0c;响应实例的返回字段是否符合参数要求。 4、利用平台的文档中心和API测试工具&#xff0c;对接口进…...

企业工程管理系统源码-数字化可视化项目管理平台

工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff1a;实现对数据字典标签的增删改查操作 2、编码管理&#xff1a;实现对系统编码的增删改查操作 3、用户管理&#xff1a;管理和查看用户角色 4、菜单管理&#xff1a;实现对系统菜单的增删改查操…...

【C语言】一文带你简单了解C语言

这里写目录标题&#xff09;引言C语言概述基础语法数据类型运算符循环语句分支语句函数数组指针文件操作内存管理高级特性结构体枚举类型联合体预处理器应用场景操作系统编译器游戏开发嵌入式系统引言 C语言是一种通用的计算机编程语言&#xff0c;具有高效、灵活、可移植等特点…...

LeetCode 589 LeetCode590 N叉树的前序遍历和后序遍历

题目&#xff1a; N叉树的前序遍历&#xff1a;给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。n 叉树 在输入中按层序遍历进行序列化表示&#xff0c;每组子节点由空值 null 分隔。 示例 1&#xff1a; 输入&#xff1a;root [1,null,3,2,4,null,5,…...

为什么CAD多段线没有面积属性或数值不对?快看过来!

有些设计师小伙伴在CAD制图过程中&#xff0c;会遇到这样的一个问题&#xff1a;在CAD图纸中直接选取线条后用工具标出来的面积是实际面积的两倍&#xff0c;而且用CAD面积查询命令直接选择对象查不出面积&#xff0c;这是为什么呢&#xff1f;本文就和小编来给大家分享一下CAD…...

WRF后处理:使用ncl脚本批量提取wrfout变量并输出/Shell 入门:Shell进入不同文件夹执行脚本

目录背景思路NCL提取wrfout特定变量Shell批量执行背景 在之前的博客WRF后处理总结我提到过将NCL与python结合进行后处理的问题&#xff0c;即&#xff0c;使用NCL进行wrfout变量的提取、计算、输出&#xff0c;再用已有python脚本绘图&#xff0c;这样可以极大节省时间。 对于…...

Consul在Windows系统下的安装与启动

1、Consul的简介 Consul 是由 HashiCorp 公司推出的一款开源工具&#xff0c;用于实现分布式系统的服务发现与服务配置。它内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key-Value 存储、多数据中心方案。 Consul 使用 GO 语言编写&#xff0c;因此天然具有可移…...

2022国赛16:神州路由器交换机BGP配置实例1

实验拓扑图 一、基本配置: R1配置: Router>ena Router#conf Router_config#host R1 R1_config#int g0/0 R1_config_g0/0#ip add 202.11.1.1 255.255.255.252 R1_config_g0/0#int l0 R1_config_l0#ip add 1.1.1.1 255.255.255.255 R1_confi...

PaddlePaddle NLP学习笔记1 词向量

文章目录1.语言模型 Language Model1.1 语言模型是什么1.2 语言模型计算什么1.3 n-gram Language Model2.神经网络语言模型NNLM2.1 N-gram模型的问题3. 词向量3.1 词向量(word Embedding)word2vec 词向量训练算法3.2 如何把词转换为词向量&#xff1f;3.3如何让向量具有语义信息…...

无重复全排列 [2*+]

目录 无重复全排列 [2*+] 程序设计 程序分析 无重复全排列 [2*+] 输出N个数的无重复全排列 Input 输入一个数值N 1<=N=50 Output 输出N个数的无重复全排列,每个数之间用空格隔开 最后一行输出无重复全排列的个数。 Sample Input 3 Sample Output 1 2...

【血泪建议】软件测试岗位现状,可惜之前没人告诉我,肠子都晦青了....

谈到现状&#xff0c;国内的软件测试行情目前呈现了两极分化的极端情况。 一个是早期的手工测试人员吐槽工作不好做&#xff0c;即使有工作也是外包&#xff0c;而且薪资太低&#xff1b;一方面是很多互联网企业感叹自动化测试人才难找&#xff0c;有技术的自动化测试工程师&a…...

Elastic(ELK) Stack 架构师成长路径

Elastic Stack&#xff08;ELK Stack&#xff09;是一个开源的日志分析平台&#xff0c;由 Elasticsearch、Logstash 和 Kibana 三个组件组成&#xff0c;主要用于数据搜索、分析和可视化。要成为一名 ELK Stack 架构师&#xff0c;需要遵循一定的成长路径&#xff0c;以便逐步…...

Netty的高性能体现在哪些方面

文章目录Netty的高性能体现在哪些方面1. 非阻塞I/O2. 零拷贝3. 内存池4. 线程模型Netty的高性能体现在哪些方面 Netty是一个高性能、异步事件驱动的网络应用程序框架&#xff0c;它具有出色的稳定性和灵活性。在现代的分布式系统和互联网应用中&#xff0c;Netty已经成为构建高…...

CompletableFuture详解

1、概述 咱们都知道可以通过继承Thread类或者实现Runnable接口两种方式实现多线程。但是有时候我们希望得到多线程异步任务执行后的结果&#xff0c;也就是异步任务执行后有返回值&#xff0c;Thread和Runnable是不能实现的。当我们需要返回值的时候怎么办呢&#xff1f; Java…...

(学习日记)2023.3.10

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…...

Umi-OCR:完全免费开源的离线OCR神器,3分钟快速上手文字识别

Umi-OCR&#xff1a;完全免费开源的离线OCR神器&#xff0c;3分钟快速上手文字识别 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚&#xff0c;扫描/生成二维…...

迪拜塔幕墙设计

迪拜塔幕墙设计 【作 者】:罗永增 【关键词】:迪拜塔,幕墙,设计,系统。 前言:...

低温预警!固化慢、易开裂……密封胶冬季施工手册

低温预警!固化慢、易开裂……密封胶冬季施工手册 硅酮耐候密封胶主要作用是保障幕墙的气密性、水密性。其出现问题,可能会导致耐候密封失效,从而造成幕墙漏水漏气,影响幕墙的正常使用。耐候密封胶由于考虑到现场施工,几乎都是单组分硅酮密封胶产品。进入冬季,气候变化明…...

【限时公开】后印象派专属--ar 16:9 --style raw --stylize 800参数组合包(含塞尚构图/修拉点彩/劳特累克动态线共12套已验证prompt模板)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;后印象派艺术精神与Midjourney风格迁移的本质逻辑 后印象派并非对印象派的简单延续&#xff0c;而是对主观表达、结构重构与象征张力的自觉回归——梵高旋转的星云、塞尚凝练的几何体、高更原始的色域&…...

5分钟掌握小红书无水印下载:让内容保存效率提升300%

5分钟掌握小红书无水印下载&#xff1a;让内容保存效率提升300% 【免费下载链接】XHS-Downloader 小红书&#xff08;XiaoHongShu、RedNote&#xff09;链接提取/作品采集工具&#xff1a;提取账号发布、收藏、点赞、专辑作品链接&#xff1b;提取搜索结果作品、用户链接&#…...

使用mcp-maker快速构建AI工具调用服务器:从协议原理到工程实践

1. 项目概述与核心价值最近在折腾AI应用开发&#xff0c;特别是想给大语言模型&#xff08;LLM&#xff09;装上更强大的“手脚”&#xff0c;让它能直接操作我电脑上的各种软件和工具。这听起来很酷&#xff0c;对吧&#xff1f;但实际操作起来&#xff0c;你会发现一个核心痛…...

Emacs AI编程助手:ai-code-interface.el深度集成指南

1. 项目概述&#xff1a;一个为Emacs注入AI灵魂的代码接口如果你是一位Emacs的深度用户&#xff0c;同时又对AI辅助编程抱有极大的热情&#xff0c;那么你很可能已经厌倦了在浏览器、终端和编辑器之间反复横跳的割裂体验。tninja/ai-code-interface.el这个项目&#xff0c;正是…...

量子私有信息检索(QPIR)技术解析与应用前景

1. 量子私有信息检索技术概述量子私有信息检索&#xff08;Quantum Private Information Retrieval, QPIR&#xff09;是密码学领域的一项突破性技术&#xff0c;它允许用户从数据库中检索特定条目而不泄露被查询的是哪个条目。这项技术的核心价值在于解决了隐私保护与数据获取…...

AI原生产品管理:多智能体协作如何重塑产品开发工作流

1. 项目概述&#xff1a;当AI成为你的产品经理最近在GitHub上看到一个挺有意思的项目&#xff0c;叫NathanJCW/ai-native-pm-cortex。光看名字&#xff0c;你大概能猜到它想做什么——“AI原生的产品经理大脑”。这可不是一个简单的聊天机器人插件&#xff0c;它试图构建一个完…...

Ash印相渲染失败率骤升47%?紧急预警:V6.2更新后Gamma 2.2→2.4迁移引发的印相断层危机

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Ash印相渲染失败率骤升47%的全局现象与危机定性 近期&#xff0c;全球多个采用 Ash 印相引擎&#xff08;v3.8.2&#xff09;的影像处理平台集中报告渲染任务异常终止、输出空白或超时中断。监控数据显…...