
- •1.Назначение динамически подключаемых библиотек
- •2. Dll и адресное пространство процесса
- •2.Создание dll
- •3.Использование dll с библиотекой импорта (неявное связывание)
- •4. Использование dll без библиотеки импорта (явное связывание)
- •5. Создание dll модуля
- •6. Порядок выполнения работы
- •7. Контрольные вопросы
3.Использование dll с библиотекой импорта (неявное связывание)
Сначала посмотрим, как использовать DLL вместе с библиотекой импорта (dlltest.lib), которая получается при компиляции предыдущего примера. Этот метод очень прост, так как в таком случае нужно просто включить заголовочный файл библиотеки и саму библиотеку в проект. Пример:
Исходный файл приложения, использующего библиотеку DLL (DLLRUN01.EXE)
#include <conio.h> #include <dlltest.h> void main() { NumberList(); LetterList(); getch(); } |
Это будет прекрасно работать, если есть заголовочный файл и библиотека импорта (dlltest.lib) находится в каталоге, прописанном в библиотечных путях. Перед запуском приложения, убедитесь, что DLL находится в каталоге, прописанном в системной переменной PATH или в том же каталоге, что и исполняемый файл, иначе вы получите сообщение об ошибке. Однако если 10 программ используют эту DLL, вам нужна всего одна ее копия, лежащая, например, в каталоге Windows\System.
Результаты работы DLLRUN01.EXE
This function was called from C:\DLLTEST\DLLRUN01.EXE NumberList(): 0 1 2 3 4 5 6 7 8 9 This function was called from C:\DLLTEST\DLLRUN01.EXE LetterList(): a b c d e f g h i j k l m n o p q r s t u v w x y z |
4. Использование dll без библиотеки импорта (явное связывание)
Теперь посмотрим, как загрузить DLL "на лету". Это нужно в случае, если не вы разрабатывали эту DLL, и у вас нет заголовочного файла и библиотеки импорта.
Исходный файл приложения, использующего библиотеку DLL - консольное приложение Win32 (DLLRUN01.EXE)
#include <windows.h> #include <iostream.h> #include <stdio.h> #include <conio.h> #define MAXMODULE 50 typedef void (WINAPI*cfunc)(); cfunc NumberList; cfunc LetterList; void main() { HINSTANCE hLib=LoadLibrary("DLLTEST.DLL"); if(hLib==NULL) { cout << "Unable to load library!" << endl; getch(); return; } char mod[MAXMODULE]; GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAXMODULE); cout << "Library loaded: " << mod << endl; NumberList=(cfunc)GetProcAddress((HMODULE)hLib, "NumberList"); LetterList=(cfunc)GetProcAddress((HMODULE)hLib, "LetterList"); if((NumberList==NULL) || (LetterList==NULL)) { cout << "Unable to load function(s)." << endl; FreeLibrary((HMODULE)hLib); return; } NumberList(); LetterList(); FreeLibrary((HMODULE)hLib); getch(); } |
Этот код загружает DLL (если она находится в путях или в текущем каталоге), а затем определяет адреса функций, которые мы будем вызывать. Конечно, в этом случае пришлось написать намного больше кода, и, соответственно, придется отловить немало ошибок. Однако такой подход более универсален.
Результаты работы DLLRUN02.EXE
Library loaded: C:\DLLTEST\DLLTEST.DLL This function was called from C:\DLLTEST\DLLRUN02.EXE NumberList(): 0 1 2 3 4 5 6 7 8 9 This function was called from C:\DLLTEST\DLLRUN02.EXE LetterList(): a b c d e f g h i j k l m n o p q r s t u v w x y z |