我在一个进程中运行,其中COMCTL32.DLL
加载了两次,一次是版本5.82.7601.17514,一次是版本6.10.7601.17514。旧版本由程序链接的旧DLL加载,而另一个版本由较新的DLL加载。
如果我使用GetModuleHandle (L"COMCTL32.DLL")
,我无法控制被解析的DLL。
当我调用GetProcAddress
到达时,例如,TaskDialogIndirect
,我得到一个空指针,这当然是因为我得到了旧DLL的句柄。
那么,当两个dll都加载时,是否有办法到达TaskDialogIndirect
的地址呢?
如果不是,我能否以某种方式确保进程加载6.10版本而不是5.82,希望我们的遗留DLL将与较新版本的COMCTL32
一起工作?
我猜你必须使用GetProcAddress()
而不是隐式链接,因为你想让你的应用程序在XP上运行,任务对话框不可用。
我可以为你看到三个选项:
- 使用隐式链接,但使用MS工具链支持的延迟加载。我不能100%确定这将给你正确的comtl32,但值得一试。
- 使用激活上下文API来确保comctl32 v6 manifest在您调用
LoadLibrary()
时发挥作用。调用LoadLibrary()
而不是GetModuleHandle()
,以确保您获得manifest魔法。 - 枚举进程中所有模块,选择正确的comcomtl32版本。有一个关于如何在MSDN上做到这一点的全面示例。
激活上下文方法是最干净的解决方案,但是激活上下文API可能很难进入。我个人使用它来确保Excel COM外接程序链接到comtl32 v6。
模块枚举方法实现起来很快,有点脏,但效果很好。