如何从一个静态库中访问当前模块的实例句柄
如果你正常编写一个静态库,则可能有这样一个需求:需要访问主链接模块的HINSTANCE(实例句柄)。我们可以要求主链接模块传递它的实例句柄到一个特殊的初始化函数中,这确实可行,但是人们经常忘记这样做,从而导致奇怪的事情发生。
如果你使用微软的链接器来链接代码,你可以使用一个链接器提供的一个虚拟变量来实现这个需求,如下图所示:
在上面的代码中,我们使用了__ImageBase这个虚拟变量来代表一个模块的DOS头部,它恰好是一个Win32模块开始的地方。换句话说,它实际上是一个模块的基地址(Base Address)。而一个模块的基地址就是一个模块的实例句柄(HINSTANCE)。
那么,这个虚拟变量就是你想要的实例句柄啦。
总结
注意,这里的ImageBase是虚拟地址空间的地址,而不是物理内存。两个不同进程启动之后,它们将会拥有不同的地址空间,从技术上来说,可执行文件可以在整块虚拟地址空间的任意位置被操作系统加载,但操作系统默认将进程加载到0x00400000的位置。
如果有这样一种情况,一个可执行程序,它加载了一些DLL模块,如果这些DLL模块拥有相同的ImageBase,会出现什么问题吗?
操作系统会这样进行处理,第一个DLL在指定的ImageBase上加载正常,而第二个会发生地址重载(rebase)。每个DLL模块的PE结构中都会有一个.reloc节,它会包含和代码更新有关的引用数据。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Accessing the current module’s HINSTANCE from a static library》
相关文章
- Android实例-解决虚拟键盘遮挡问题(XE8+小米2)
- 静态方法和实例化方法的区别
- 动态修改Python类和实例的方法(转)
- SVG实例之电力开关
- MySQL增量备份与恢复实例
- 【学习总结】Python-3-风格各异的数值类型实例
- 静态变量和实例变量的区别
- SAP CRM CL_CRM_BOL_ENTITY实例的sendable属性是什么时候置位的
- PHP 实例 - AJAX RSS 阅读器
- Java中 类变量(static静态变量)和实例变量(非静态变量)的区别
- Python编程:Flask扩展Flask-WTF和Flask-SQLAlchemy应用实例
- LVDS收发传输实例
- 阿里云服务器包年包月/按量计费/抢占式实例模式选择方法
- Kernel:性能分析实例(一)
- C#创建Windows窗体应用程序实例4【大学选课】
- (12)yolov5+deepsort 应用实例之跟踪目标起始时间并记录结果图像
- Python爬虫爬取某电影排行榜图片实例