操作系统|如何从一个静态库中访问当前模块的实例句柄
文章图片
如果你正常编写一个静态库 , 则可能有这样一个需求:需要访问主链接模块的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》
- 小米科技|不聊性能只谈拍照!新旗舰反向升级成潮流,拍照手机如何选?
- 三星|试图挽回中国市场,国际大厂不断调价,从高端机皇跌到传统旗舰价
- 搜索引擎|淘宝运营系统出台春节打烊功能,淘宝运营商家该如何选择?
- 小米科技|RTX3060的性能到底如何?相比RTX2060提升有多大?
- 苹果|从5499元跌至3399元,苹果A14+IP68防水,旧款iPhone加速清仓
- 小米科技|从4999跌至2889元,2K曲面屏+IP68防水,小米老款旗舰售价大跳水
- 骁龙855|从3499元跌至1190元,5000mAh+骁龙855,适合玩游戏
- 市值超 1.7 万亿的Netflix是如何做决策的?
- 京东|国资入场!从80亿增加到300亿,蚂蚁金融的“改变”已经开始
- 60秒长语音不用再从头听了!微信迎来“史诗级更新”