GetModuleHandle и GetProcAddress, когда COMCTL32.DLL загружается дважды - PullRequest
1 голос
/ 31 августа 2011

Я работаю внутри процесса, где COMCTL32.DLL загружается дважды, один раз с версией 5.82.7601.17514 и один раз с версией 6.10.7601.17514.Устаревшая версия загружается некоторой устаревшей DLL, с которой связана программа, а другая версия загружается более новой DLL.

Если я использую GetModuleHandle (L"COMCTL32.DLL"), у меня нет контроля над DLL, которая разрешается.

Когда я вызываю GetProcAddress для достижения, например, TaskDialogIndirect, я получаю нулевой указатель обратно, что, безусловно, потому, что я вернул дескриптор устаревшей DLL.

Итак,есть ли какие-то способы добраться до адреса, скажем TaskDialogIndirect, когда обе DLL загружены.

Если нет, могу ли я как-то убедиться, что процесс загружает версию 6.10, а не 5.82, в надеждечто наша старая DLL будет нормально работать с новой версией COMCTL32?

1 Ответ

5 голосов
/ 31 августа 2011

Полагаю, вам нужно использовать GetProcAddress() вместо неявных ссылок, потому что вы хотите, чтобы ваше приложение работало на XP, где диалог задач недоступен.

Я вижу для вас три варианта:

  1. Использовать неявное связывание, но использовать задержку загрузки, поддерживаемую цепочкой инструментов MS. Я не уверен на 100%, что даст вам правильный comctl32, но стоит попробовать.
  2. Используйте API-интерфейс активации , чтобы убедиться, что манифест comctl32 v6 работает, когда вы вызываете LoadLibrary(). Позвоните LoadLibrary() вместо GetModuleHandle(), чтобы убедиться, что вы получаете манифестную магию.
  3. Перечислите все модули в процессе и выберите правильную версию comctl32. Существует подробный пример того, как это сделать на MSDN .

Подход с использованием контекста активации - самое чистое решение, но API контекста активации может оказаться непростым. Я лично использовал его, чтобы убедиться, что надстройка Excel COM ссылается на comctl32 v6.

Подход к перечислению модулей является быстрым, немного грязным, но хорошо работает.

...