文章图片
如果你正常编写一个静态库 , 则可能有这样一个需求:需要访问主链接模块的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》
- 德尔塔|新冠病毒“最厉害变种”来袭,或从艾滋病患者体内进化而来
- |脊椎动物一路向前,从此改变了我们的生物世界!
- 单片机|快2022年,从事单片机/硬件开发前景到底如何?
- 银河系|银河系和仙女座星系的碰撞已经开始?太阳系未来的命运会如何?
- |如何区分三相电源的相序?
- 银黑狐|罕见银黑狐现身北京门头沟,如狗般乖巧,它们是如何被驯化的?
- 魅族|从3999降至2499,8+256GB、三星定制屏,魅族也有高性价比
- 新型冠状肺炎|曾经危机地球的生机,氧气如何慢慢变成了“毒气”
- 音箱|人类高质量监听书架音箱推荐,从劲浪、JBL到丹拿,九个品牌简评
- |如果我们能控制时间,那会如何?答案无法想象