动态链接库(一)--动态链接库简介

2023-10-27

写在前面

自从微软推出的第一个版本的Windows操作系统以来,动态链接库(DLL)一直就是Windows操作系统的基础。

动态链接库通常不能直接运行,也不能接收消息。它们一直是独立的文件,其中包含能被可执行程序或其他DLL文件调用来完成某项工作的函数。只有在其他模块调用动态链接库中的函数时,它才能发挥作用。在实际编程时,我们可以把完成某种功能的函数放在一个动态链接库中,提供给其他程序调用。

Windows API中所有的函数都包含在DLL中,其中有3个最重要的DLL:
①Kernel32.dll
它包含用于管理内存、进程和线程的函数,例如CreateThread函数。
②User32.dll
它包含用于执行用户界面任务(如窗口的创建和消息的传递)的函数,例如CreateWindow函数。
③GDI32.dll
它包含用于画图和显示文本的函数

静态库和动态库

静态库

函数和数据被编译进一个二进制文件中(扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.exe文件)。当发布产品时,只需要发布这个可执行文件即可,并不需要发布被使用的静态库。

动态库

在使用动态库的时候,往往提供两个文件:一个引入库文件和一个DLL(.dll)文件。

注意:
虽然引入库文件的后缀名也是”.lib”,但该文件和静态库的”.lib”文件有着本质上的区别。

静态库的”.lib”文件包含数据和函数的声明实现,而动态库的”.lib”引入库文件则仅包含导出的函数和变量的符号名(声明),而在DLL文件中才包含实际的函数和数据。

在使用动态库的情况下,在编译链接可执行文件时,只需要链接该DLL的引入库文件,该DLL中的函数代码和数据并不复制到可执行文件中,直到可执行程序运行时,才去加载所需的DLL,将DLL映射到进程的地址空间中,然后访问DLL中的导出函数。

这时,在发布产品时,除了发布可执行文件以外,还要发布该程序将要调用的动态链接库(dll)。

动态链接库的优势

①可以采用多种编程语言来编写
我们可以采用自己数据的开发语言编写DLL,然后由其他语言编写的可执行程序来调用这些DLL。

②增强产品的功能
在发布产品时, 可以发布产品功能实现的动态链接库规范, 让使用该动态链接库的开发人员遵循这个规范开发自己的DLL, 以取代产品原有DLL, 让产品调用新的dll, 因此实现增强产品的功能.

③提供二次开发的平台
可以采用DLL的形式提供一个二次开发的平台, 让用户可以利用该DLL中已实现的功能, 封装成自己需要的符合业务需求的DLL, 实现二次开发.

④简化项目管理
在一个大型的项目中, 可以将项目细分, 将不同的功能交由各个项目小组以DLL的形式实现, 以同步协作推进项目.

⑤可以节省磁盘空间和内存
假如多个程序都会用到一个DLL, 那么加载时只会加载一次, 然后和其他进程共享, 以节省内存.

⑥有助于资源的共享
DLL可以包含对话框模板, 字符串, 图标, 位图等资源, 假如多个应用程序会用到同一个对话框模板, 或者图标等, 可以将这些对话框和图标等资源封装到一个DLL中, 以供多个程序使用.

⑦有助于实现应用程序的本地化
如果产品需要提供多种语言版本, 那么可以使用DLL来支持多语言, 可以为每种语言创建一种只支持该语言的DLL.

动态链接库的加载

隐式加载

  1. 可以在项目属性 -> 链接器 -> 附加依赖项 中输入所需动态链接库的引入库文件(.lib文件), 然后将DLL文件放到执行目录下
  2. 也可通过#pragma comment(lib, 引入库文件路径), 来隐式加载, 同时也需要将DLL文件放到执行目录下.

项目属性导入引入库文件

//注意路径, 这里会以当前文件的路径去查找Dll1.lib文件
#pragma comment(lib, "Dll1.lib")

显式加载

显式加载步骤:
①程序目录下要存在dll文件
②通过LoadLibrary函数加载
③通过GetProcAddress获取导出函数地址
④程序中通过获取到的函数指针调用接口
⑤使用完dll后通过FreeLibrary函数释放对dll的引用

小结

这里仅简单的介绍了下动态链接库的相关知识及使用, 后面会详细的介绍如何使用动态链接库, 使用时的注意事项, 如何创建自己的dll或二次开发他人的dll.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态链接库(一)--动态链接库简介 的相关文章

  • “此应用程序已请求运行时以异常方式终止它”的原因是什么?

    Visual C 运行时抛出一个常见错误 此应用程序已请求运行时以异常方式终止它 请联系应用程序的支持团队以获取更多信息 该错误消息实际上是什么意思mean 让我用一个比喻来准确地解释我的问题 如果我看到一条消息 异常 访问冲突 0xc00
  • 如何在子 shell 中运行 cmd.exe 批处理文件

    我有一个批处理文件 通常像这样调用 longjob cmd gt result txt 2 gt 1 这工作正常 但脚本在执行过程中更改了目录 将我的 shell 留在该目录中 这很麻烦 有没有办法在子 shell 中运行命令 同时仍然允许
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 如何获取Windows批处理的父文件夹

    我正在编写一个批处理文件 我需要获取该bat文件的父文件夹 有可能吗 注意 我的意思是批处理文件的父文件夹 而不是调用该批处理的提示的当前目录 Thanks 批处理的父文件夹位于变量中 dp0位于 例子 echo off setlocal
  • 批处理脚本 FOR 循环仅设置输出的第一个字母 wsl --list -q

    我正在编写一个批处理脚本 将文件从 Windows 目录复制到 WSL 发行版 其中一部分是选择将文件复制到哪个发行版 如果我使用命令wsl list q如果给我以下输出 Ubuntu 22 04 Ubuntu 18 04 我正在尝试使用此
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • Rails Windows Vagrant 响应时间非常慢

    我在跑 Vagrant 1 7 1 Rails 4 1 4 Thin 1 6 1 Windows 7 每个静态文件的发送时间都超过一秒 在我的 PC 上加载一个页面可能需要大约 20 秒 而在同事的 Linux 机器上则只需瞬间 有一些帖子
  • 如何设置任务在使用 vbs 登录时以当前用户身份运行而无需管理员权限?

    从命令行 我可以创建一个在登录时运行的计划任务 无需管理员权限或用户输入密码来设置任务 但是我必须使用 xml 文件来执行此操作 下面是一个示例 xml 其中 Domain User 部分必须在运行时替换为当前用户的域和名称
  • git 认为文件已更改

    我在一台机器上对一个项目做了一些工作 然后推送到 github 在另一台机器上克隆并做了一些工作 然后推送 然后我回到第一台机器并做了一个pull 现在 第一台机器认为项目中最初的所有文件都已更改 我试过了 git checkout f a
  • C# WMI 在远程 PC 上运行一个 exe,然后在同一台 PC 上运行另一个 exe,然后在网络路径上调用 Directory.CreateDirectory 并失败

    使用 C WMI 我在另一台计算机上启动一个 exe 该 exe 使用 C 启动另一个 exeProcess班级 最后一个 exe 尝试调用Directory CreateDirectory使用网络路径 又名 comp1 d dir Dir
  • 可以读取目标文件吗?

    我很好奇 obj文件 我几乎不知道它们是什么 或者它们包含什么 所以我用 Vim 文本编辑器打开它们 我在里面发现了一种类似外星人的语言 有什么办法可以理解它们代表什么以及它们的内容是什么 另外 它们的用途是什么 Thanks Sure 但
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • Visual C++ 找不到“Windows 类型”,如 PVOID、DWORD、ULONG 等

    Windows 似乎无法找到任何这些类型 我完全不知道该怎么办 我在 MSDN 上找到的东西似乎表明它们是默认包含的 但它们在 Native 程序或 CLR 程序中不起作用 我收到的具体错误是
  • 如何在 Windows 下向 .sh 脚本传递参数?

    我正在尝试在 Windows 下执行 sh 脚本 我安装了 Git 它允许我执行 sh 文件 但是 如果不使用 sh 作为执行前缀 我似乎无法传递任何参数 我的 sh 文件 echo Test 1 如果我用以下命令执行它 gt sh tes
  • 在 Windows 上查找父进程 ID

    Problem 给定远程 Windows 主机上的进程 ID 和命令行访问权限 如何找到其父进程的 PID Solution 鉴于 Marc B 的回答 我们可以使用 WMIC 命令示例here https learn microsoft
  • 如何以管理员身份在 rake 任务中运行 shell 命令?

    我有一个简短的 cmd 文件 我想将其作为部署过程的一部分运行 不幸的是 cmd 文件需要管理员权限 是否可以从 rake 中获得管理员权限 或者我是否需要以管理员身份启动 shell 您可以尝试runas http ss64 com nt
  • 如何批量获取子字符串在字符串中的位置

    获取子串的位置 Set str1 This is Test string Set sstr Test 这里我需要获取 Test 8 的位置 谢谢 echo OFF SETLOCAL Set str1 This is Test string
  • 如何将 Hudson/Jenkins 参数传递给 Windows 批处理命令

    好吧 我需要在我的 Hudson 作业中执行一个批处理文件 我有一个参数 Jenkis 参数 我需要将这个值 如参数 传递给批处理文件 我尝试了以下操作 Deploy cmd configuration DEPLOYCONFIGURATIO
  • 已达到网络 BIOS 命令限制

    我的 ASP Net 应用程序从另一台 Windows 服务器上的共享文件夹获取文件 当请求增加时 我收到以下错误 The network BIOS command limit has been reached 我已按照以下步骤操作微软 K

随机推荐

  • 用户态文件系统fuse学习

    FUSE概述 FUSE 用户态文件系统 是一个实现在用户空间的文件系统框架 通过FUSE内核模块的支持 使用者只需要根据fuse提供的接口实现具体的文件操作就可以实现一个文件系统 在fuse出现以前 Linux中的文件系统都是完全实现在内核
  • Zabbix 系统监控(二)Linux 系统监控

    windows 系统硬件信息获取 linux 系统监控 linux 系统硬件信息获取 5 windows 系统硬件信息获取 本文通过在 OS 操作系统层面上 主要获取 windows 服务器下 CPU 信息 内存信息 硬盘信息 操作系统 服
  • spring 生命周期

    spring 生命周期 IOC容器 1 加载配置文件 2 资源定位 3 资源解析 4 生成BeanDefinition元信息 5 通过工厂把BeanDefinition加载到容器中 初始化bean实例 由spring产生的bean默认是单例
  • 【论文笔记15】以太坊智能合约去中心化的链上数据访问

    原文作者 Mohd Sameen Chishti Farhan Sufyan and Amit Banerjee Member IEEE 原文标题 Decentralized On Chain Data Access via Smart C
  • Oracle建表报错:ORA-00955:名称已由现有对象使用

    现象描述 在Oracle数据库中已经创建了 staff表 现在因为业务需求 创建与staff表结构相同的测试表 test staff test staff表创建语句如下所示 create table test staff STAFF ID
  • Javeweb项目微服务集群部署

    基于Springcloud的javaweb项目部署集群环境 采用jdk运行 jar包 consul 进行注册服务监控健康 实现并发量大的时候可以快速响应的高并发效果 操作过程如下 1 安装nfs服务 2 安装相应中间件服务 3 安装数据库以
  • MySQL - 唯一索引

    唯一索引 所谓唯一索引 就是在创建索引时 限制索引的字段值必须是唯一的 通过该类型的索引可以比普通索引更快速地查询某条记录 1 创建表时定义索引 CREATE TABLE tablename propname1 type1 propname
  • 利用用adb查看短信、通讯录、拨号的应用数据

    利用用adb查看短信 通讯录 拨号的应用数据 1 进入root界面 adb shell su 2 查看你想要查看的应用手机目录下应用界面的包名 adb shell dumpsys activity findstr mFocusedActiv
  • 第 0004 题: 任一个英文的纯文本文件,统计其中的单词出现的个数

    import os file open wz txt mode r dict for line in file h line line split for key in h line if key 1 gt a and key 1 lt z
  • Centos-启动network报错RTNETLINK answers: File exists解决方法

    背景 今天在Vcenter上 用模板克隆了一个虚拟机 启动之后 网卡启动不了 报错如下 RTNETLINK answers File exists 说明 环境 Centos6 6 X64 网卡两个 原因 由于用模板克隆虚拟机 所以网卡的配置
  • ts类型体操Concat

    533 Concat by Andrey Krasovsky bre30kra69cs easy array Question Implement the JavaScript Array concat function in the ty
  • 总结的一些MySQL索引相关的知识点

    博客迁移 http cui zhbor com article 14 html MySQL索引 有很多很多的东西需要去学习 我会写一些自己的总结 这些总结主要是平时运用在实际项目中的 有很多的经验往往设计表的人很清楚 但是总是有 这个东西就
  • 【实例分割】3、Mask Scoring R-CNN

    文章目录 摘要 1 引言 2 相关工作 2 1 实例分割 2 2 检测得分校正 3 方法 3 1 动机 3 2 Mask scoring in Mask R CNN 4 实验 4 1 实验细节 4 2 定量结果分析 4 3 消融学习 4 4
  • 时序逻辑和组合逻辑

    一 组合逻辑与时序逻辑的对比 1 组合逻辑的输出状态与输入直接相关 时序逻辑还必须在时钟上升沿触发后输出新值 2 组合逻辑容易出现竞争 冒险现象 时序逻辑一般不会 3 组合逻辑的时序较难保证 时序逻辑更容易达到时序收敛 时序逻辑可控 4 组
  • IP代理安全吗?如何防止IP被限制访问?

    你是否遇到过可以正常上网 但访问某个网站却被禁止 注册某个网站账号 却被封号 那都是因为IP出现问题 您的IP地址透露很多关于您的信息 包括您的位置和互联网活动 在本文中 我们将一起了解IP地址 网站如何利用它来跟踪您 以及与IP代理如何帮
  • 求助:stm32+proteus+adc采集电压仿真显示为零

    求助一下大佬 因为板子上的oled不是ssd1306驱动的所以现在只能学习跑仿真 在学adc采集电压的实验 OLED显示没问题 现在的问题是采集不到电压 显示总是0 麻烦好心人帮我看看是哪里出了问题 软件用的keil mdk5 24 pro
  • Game【HDU-6873】【Splay】

    2020 Multi University Training Contest 9 G题 题意 有N个有各自高度的位置 按1 N从左到右排列 现在我们有两种操作 x y将第x列 第y行的方块 包括它上面的方块从右往左的移动过去 同时推动前面的
  • 【导入导出测试用例编写】

    导入导出测试用例编写 一 导出模板测试用例 二 导出数据测试用例 三 导入数据测试用例 一 导出模板测试用例 1 检查模板是否可以正常下载正常打开 2 检查模板表头格式展示是否正确 与系统列表中的字段是否一致 3 检查必填项 字段长度 字段
  • 接口性能 指标

    接口测试响应时间 通用得接口响应使时间分布情况 100ms为优良 500ms为及格 1000ms以上为不可忍受 金融接口响应时间得分布情况 100ms为优良 200ms为及格 300ms以上为不可忍受
  • 动态链接库(一)--动态链接库简介

    写在前面 自从微软推出的第一个版本的Windows操作系统以来 动态链接库 DLL 一直就是Windows操作系统的基础 动态链接库通常不能直接运行 也不能接收消息 它们一直是独立的文件 其中包含能被可执行程序或其他DLL文件调用来完成某项