Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Создание эффективных приложений для Windows Джеффри Рихтер 2004 (Книга).pdf
Скачиваний:
377
Добавлен:
15.06.2014
Размер:
8.44 Mб
Скачать

влияет на характер работы _delayLoadHelper. Если Вы хотите изменить поведение _delayLoadHelper, начните с DliHook и модифицируйте ее код так, как Вам требуется. Потом передайте ее адрес функции _delayLoadHelper.

В статически подключаемой библиотеке DelayImp.lib определены двс глобальные переменные типа PfriDliHouk: __pfnDliNotifyHook и __pfnDliFailureHook:

typedef FARPROC (WINAPI *pfnDliHook)( unsigned dliNotify, PDelayLoadInfo pdli);

Как видите, это тип данных, соответствующий функции, и он совпадает с прототипом моей DliHook. В DelayImp.lib эти две переменные инициализируются значением NULL, которое сообщает __delayLoadHelper, что никаких функций-ловушек вызывать не требуется. Чтобы Ваша функция-ловушка все же вызывалась, Вы должны присвоить ее адрес одной из этих переменных. В своей программе я пpocтo добавил на глобальном уровне две строки:

PfnDliHook __pfnDliNotifyHook = DliHook;

PfnDliHook __pfnDliFailureHook = DliHook;

Так что __delayLoadHelper фактически работает с двумя функциями обратного вызова: одна вызывается для уведомлений, другая — для сообщений об ошибках. Поскольку их прототипы идентичны, а первый параметр, dliNotify, сообщает о причине вызова функции, я всегда упрощаю себе жизнь, создавая одну функцию и настраивая на нее обе переменные.

Механизм отложенной загрузки DLL, введенный в Visual C++ 6.0, — вещь весьма интересная, и я знаю многих разработчиков, которые давно мечтали о нсм. Он будет полезен в очень большом числе приложений (особенно от Microsoft).

Программа-пример DelayLoadApp

Эта программа, «20 DelayLoadApp.exe» (см. листинг на рис. 20-6), показывает, как использовать все преимущества DLL отложенной загрузки. Для демонстрации нам понадобится небольшой DLL-файл; он находится в каталоге 20-DclayLoadLib на компактдиске, прилагаемом к книге.

Так как программа загружает модуль «20 DelayLoadLib» c задержкой, загрузчик не проецирует его на адресное пространство процесса при запуске. Периодически вызывая функцию IsModuleLoaded, программа выводит окно, которое информирует, загружен ли модуль в адресное пространство процесса. При первом запуске модуль «20 DelayLoadd.lib» не загружается, о чем и сообщается в окне (рис. 20-4).

Рис. 20-4. DelayLoadApp сообщает, что модуль «20 DelayLoadLib» не загружен

Далсс программа вызывает функцию, импортируемую из Dl.L, и это заставляет __delayLoadHelper автоматически загрузить нужную DLL. Когда функция всрнст управление, программа выведет окно, показанное на рис. 20-5.