IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES)的缺陷 -> 正文阅读

[C++知识库]LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES)的缺陷

如果你认真瞧过LoadLibraryEx函数的文档,就会发现它有这样一个标志
DONT_RESOLVE_DLL_REFERENCES。关于此标志,文档是这样描述的:

如果使用了此标志,并且加载的是一个DLL模块,系统在进程和线程初始化/退出的时候,不会调用DllMain,同时,系统也不会加载该模块引用的其他模块。
如果你系统仅仅是访问DLL模块中的数据或者是资源的话,则使用LOAD_LIBRARY_AS_DATAFILE会是一个更佳的选择。

在我看来,上面所建议的LOAD_LIBRARY_AS_DATAFILE还远远不够。
因为,
DONT_RESOLVE_DLL_REFERENCES这个标志实际上有点类似于一个”定时炸弹”。

请再次认真阅读下关于这个标志的文档,试着深入地理解它会做什么以及它不会做什么。
模块被加载到内存的时候,系统不会调用它的初始化函数,并且其所有依赖的模块也不会被加载。结果就是,你无法执行此模块中的任何代码。(说得更准确地的话,就是如果你试图执行该模块中的代码,会导致程序崩溃,一万DLL模块还未初始化其自身,并且它的DLL导入表都没有得到解析)
但是,和LOAD_LIBRARY_AS_DATAFILE标志不同的是,被加载的DLL可以被GetModuleHandle所发现,并且可以使用GetProcAddress。

很明显,对于一个使用了标志进行加载的模块使用GetProcAddress是一个坏主意。因为上面我们提到过,你根本无法执行这个DLL中的任何代码。那从DLL中获取一个函数入口点又有什么意义呢?

而GetModuleHandle就会触发这个定时炸弹。

使用GetModuleHandle来查看一个DLL是否已经加载了是一个很常见的使用场景,如果加载了,则继续使用GetProcAddress来获取一个函数的地址并调用它。如果DLL使用的是
DONT_RESOLVE_DLL_REFERENCES标志来加载的话,GetModuleHandle和GetProcAddress将会调用成功,但是执行函数的时候会导致程序崩溃。执行这种操作的代码不知道DLL是使用?DONT_RESOLVE_DLL_REFERENCES 加载的,它没有办法保护自己。

(请注意,这样做的代码无论如何都是不安全的,因为最初加载 DLL 的代码可能会在另一个线程上执行 FreeLibrary,从而导致代码从第一个线程下面被撕掉。第二个问题可以通过使用 GetModuleHandleEx”修复”这个问题,可以通过指定它增加 DLL 引用计数,但这并不能解决第一个问题。)

即使你使用LoadLibrary加载DLL并将该句柄传递给GetProcAddress,程序仍然会崩溃,因为LoadLibrary注意到DLL已加载并且只是增加引用计数。

我们看看下面的例子:

如果你在没有命令行参数的情况下运行这个程序,那么一切都会正常运行:记事本会顺利启动。 但是,如果你传递一个命令行参数,这会启动”定时炸弹”,并且对 ShellExecuteA 的调用会导致程序崩溃,因为 shell32.dll 是在没有解析其 DLL 引用的情况下加载的。

换句话说,
DONT_RESOLVE_DLL_REFERENCES 从根本上说是有缺陷的,应该避免。 它继续存在只是为了向后兼容。

总结

太长不看版:任何情况下,请勿使用
DONT_RESOLVE_DLL_REFERENCES,保护他人,也保护自己。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《LoadLibraryEx(
DONT_RESOLVE_DLL_REFERENCES) is fundamentally flawed》

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-06 10:54:21  更:2022-05-06 10:54:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 2:02:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码