Составители:
2. Позднее явное связывание. Хотя данный тип связывания преодолевает ограни-
чения во время загрузки, это метод требует большой работы над приложением. Вместо
указания DLL-процедур на стадии компиляции приложение использует функции
LoadLibrary(), LoadLibraryEx(), GetProcAddress() и FreeLibrary(), чтобы задать во время
выполнения имена DLL-библиотек и процедур, на которые будут выполнятся ссылки.
Кроме того, позднее явное связывание позволяет приложению поддерживать
функциональные возможности, недопустимые на этапе создания приложения. Напри-
мер, текстовый процессор может предоставлять внутри DLL подпрограммы преобразо-
вания файлов различного формата. При использовании динамического связывания во
время выполнения возможно добавление новых DLL-библиотек, содержащих подпро-
граммы преобразования новых форматов, которых не было на момент создания прило-
жения. Поскольку приложение во время выполнения определяет, какие DLL-библиотеки
преобразования форматов существуют, в результате установки новых DLL приложение
получит возможность использования новых процедур преобразования. Для извлечения
имен существующих DLL приложение применяет функции FindFirstFile() и
FindNextFile(). Затем оно может загрузить каждую DLL, получить адреса процедур пре-
образования и поместить эти адреса в структуру, которая впоследствии будет задейство-
вана в процессе преобразования файлов.
Первое, что необходимо сделать при динамической загрузке DLL, - это поместить
модуль библиотеки в память процесса. Данная операция выполняется с помощью функ-
ции LoadLibrary(), имеющей единственный аргумент lpFileName - имя загружаемого мо-
дуля. Соответствующий фрагмент программы должен выглядеть следующим образом:
HINSTANCE hMyDll;
if ( (hMyDll=:: LoadLibrary ( "MyDLL") ) ==NULL) { / * не удалось загрузить DLL */ }
else { /* приложение имеет право пользоваться функциями DLL через hMyDll
*
/ }
Стандартным расширением файла библиотеки Windows считает .dll, если не ука-
зать другое расширение. Если в имени файла указан и путь, то только он будет исполь-
зоваться для поиска файла. В противном случае Windows будет искать файл по той же
схеме, что и в случае неявно подключенных DLL, начиная с каталога, из которого за-
гружается ехе-файл, и продолжая в соответствии со значением PATH.
Когда Windows обнаружит файл, его полный путь будет сравнен с путем библио-
тек DLL, уже загруженных данным процессом. Если обнаружится тождество, вместо за-
грузки копии приложения возвращается дескриптор уже подключенной библиотеки.
Если файл обнаружен и библиотека успешно загрузилась, функция LoadLibrary()
возвращает ее дескриптор, который используется для доступа к функциям библиотеки.
Расширенная функция LoadLibraryEx() получает три параметра:
HMODULE (LPCTSTR lpFileName, // имя загружаемого модуля,
HANDLE hFile, // зарезервирован, должен быть нулевым
DWORD dwFlags); // флаги, определяющие опции загрузки модуля
Перед тем, как использовать функции библиотеки, необходимо получить их адрес.
Для этого сначала следует воспользоваться директивой typedef для определения типа
указателя на функцию и определить переменную этого нового типа, например:
// тип PFH_MyFunction будет объявлять указатель на функцию,
// принимающую указатель на символьный буфер и выдающую значение типа int
typedef int (WINAPI *PFH_MyFunction) (char *);
44
2. Позднее явное связывание. Хотя данный тип связывания преодолевает ограни-
чения во время загрузки, это метод требует большой работы над приложением. Вместо
указания DLL-процедур на стадии компиляции приложение использует функции
LoadLibrary(), LoadLibraryEx(), GetProcAddress() и FreeLibrary(), чтобы задать во время
выполнения имена DLL-библиотек и процедур, на которые будут выполнятся ссылки.
Кроме того, позднее явное связывание позволяет приложению поддерживать
функциональные возможности, недопустимые на этапе создания приложения. Напри-
мер, текстовый процессор может предоставлять внутри DLL подпрограммы преобразо-
вания файлов различного формата. При использовании динамического связывания во
время выполнения возможно добавление новых DLL-библиотек, содержащих подпро-
граммы преобразования новых форматов, которых не было на момент создания прило-
жения. Поскольку приложение во время выполнения определяет, какие DLL-библиотеки
преобразования форматов существуют, в результате установки новых DLL приложение
получит возможность использования новых процедур преобразования. Для извлечения
имен существующих DLL приложение применяет функции FindFirstFile() и
FindNextFile(). Затем оно может загрузить каждую DLL, получить адреса процедур пре-
образования и поместить эти адреса в структуру, которая впоследствии будет задейство-
вана в процессе преобразования файлов.
Первое, что необходимо сделать при динамической загрузке DLL, - это поместить
модуль библиотеки в память процесса. Данная операция выполняется с помощью функ-
ции LoadLibrary(), имеющей единственный аргумент lpFileName - имя загружаемого мо-
дуля. Соответствующий фрагмент программы должен выглядеть следующим образом:
HINSTANCE hMyDll;
if ( (hMyDll=:: LoadLibrary ( "MyDLL") ) ==NULL) { / * не удалось загрузить DLL */ }
else { /* приложение имеет право пользоваться функциями DLL через hMyDll */ }
Стандартным расширением файла библиотеки Windows считает .dll, если не ука-
зать другое расширение. Если в имени файла указан и путь, то только он будет исполь-
зоваться для поиска файла. В противном случае Windows будет искать файл по той же
схеме, что и в случае неявно подключенных DLL, начиная с каталога, из которого за-
гружается ехе-файл, и продолжая в соответствии со значением PATH.
Когда Windows обнаружит файл, его полный путь будет сравнен с путем библио-
тек DLL, уже загруженных данным процессом. Если обнаружится тождество, вместо за-
грузки копии приложения возвращается дескриптор уже подключенной библиотеки.
Если файл обнаружен и библиотека успешно загрузилась, функция LoadLibrary()
возвращает ее дескриптор, который используется для доступа к функциям библиотеки.
Расширенная функция LoadLibraryEx() получает три параметра:
HMODULE (LPCTSTR lpFileName, // имя загружаемого модуля,
HANDLE hFile, // зарезервирован, должен быть нулевым
DWORD dwFlags); // флаги, определяющие опции загрузки модуля
Перед тем, как использовать функции библиотеки, необходимо получить их адрес.
Для этого сначала следует воспользоваться директивой typedef для определения типа
указателя на функцию и определить переменную этого нового типа, например:
// тип PFH_MyFunction будет объявлять указатель на функцию,
// принимающую указатель на символьный буфер и выдающую значение типа int
typedef int (WINAPI *PFH_MyFunction) (char *);
44
Страницы
- « первая
- ‹ предыдущая
- …
- 40
- 41
- 42
- 43
- 44
- …
- следующая ›
- последняя »
