GetModuleHandle and GetProcAddress when COMCTL32.DLL is loaded twice
I am running inside a process where COMCTL32.DLL
is loaded twice, once with the version 5.82.7601.17514 and once with the version 6.10.7601.17514. The legacy version is loaded by some legacy DLL 开发者_StackOverflowthe program is linked with, and the other version is loaded by a newer DLL.
If I use GetModuleHandle (L"COMCTL32.DLL")
I have no control over the DLL which gets resolved.
When I call GetProcAddress
to reach, for instance, TaskDialogIndirect
, I get a null pointer back, which is certainly because I got back the handle of the legacy DLL.
So, is there some means of getting to the address of, say TaskDialogIndirect
when both DLLs are loaded.
If not, can I somehow make sure that the process loads the 6.10 version and not the 5.82, in the hope that our legacy DLL will work fine with the newer version of COMCTL32
?
I guess you are having to use GetProcAddress()
rather than implicit linking because you want your app to run on XP where task dialog is not available.
I can see three options for you:
- Use implicit linking, but use delay loading as supported by the MS tool chain. I'm not 100% certain that will give you the correct comctl32 but it's worth a try.
- Use the activation context API to make sure that the comctl32 v6 manifest is in play when you call
LoadLibrary()
. CallLoadLibrary()
rather thanGetModuleHandle()
to make sure that you get the manifest magic. - Enumerate all the modules in the process and select the correct version of comctl32. There is a comprehensive example of how to do this on MSDN.
The activation context approach is the cleanest solution, but the activation context API can be tricky to get into. I personally have used it to ensure that an Excel COM add-in links to comctl32 v6.
The module enumeration approach is quick to implement, somewhat dirty, but will work well.
精彩评论