Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум «Основы разработки приложений Windows» книга 2.DOC
Скачиваний:
91
Добавлен:
10.05.2014
Размер:
827.9 Кб
Скачать

Работа 15. Библиотеки динамической компоновки

a. Неявное (статическое) подключение.В этом случаеDLL-библиотека автоматически проецируется на адресное пространство вызывающей программы еще в процессе ее запуска. Создайте проект с именем, например,DLL.IDEдля подготовки выполнимогоDLL-модуля. В окнеTargetTypeукажите тип приложенияDynamicLibrary(.dll). Исключите из проекта файлы .RC и .DEF.

В исходный текст программы DLL-библиотеки включите две прикладные функции-подпрограммы с произвольными именами (например,Func1иFunc2), которые вызовом функцииMessageBox()выводят в окно сообщения различающуюся информацию. Исходный текст библиотеки должен состоять только из этих функций (без функцииWinMain()). В начале программы, как обычно, должны быть описаны прототипы этих функций, в которых перед типом возвращаемого значения следует указать описатель__declspec (dllexport) (заметьте, что этот описатель начинается сдвухсимволов подчеркивания). Включите в текст программы директиву #includeдля подсоединения заголовочного файлаWindows.h.

В результате компиляции и компоновки должны создаться файлы DLL.DLLиDLL.LIB. Удостоверьтесь в этом.Не запускайтеполученный модульDLL.DLL; он предназначен не для самостоятельной работы, а для вызова из программы .EXE.

Создайте второй проект с именем, например, CPP.IDEдля подготовки выполнимого модулявызывающейпрограммы. В окнеTargetTypeэтого проекта укажите, как обычно, тип приложенияApplication(.exe).В состав проекта включите, помимо исходного файлаCPP.CPP, еще и файл библиотеки импортаDLL.LIB, с помощью которой осуществляется поиск и привязка к выполнимому модулю вызываемых в немDLL-библиотек.

В функцию WinMain()вызывающей программы включите сначала вывод в окно сообщения какой-либо информационной строки, чтобы при запуске программы удостовериться, что она начала работать, а затем – вызовы первой и второй функцийDLL-библиотеки. Перед функциейWinMain()опишите прототипы вызываемых функций с описателем__declspec (dllimport).

Откомпилируйте программу CPP.EXE. Запустив программу на выполнение, убедитесь, что она вызывает обе функции созданной вамиDLL-библиотеки. Просмотрите с помощью какого-либо текстового редактора содержимое файла библиотеки импортаDLL.LIBи найдите в нем “декорированные” компоновщиком имена ваших функций. Запишите эти имена, чтобы воспользоваться ими в следующем задании. Для определения “декорированных” имен можно также вызвать утилитуTDUMPв таком формате:

TDUMP имя_dll.DLL имя_dll.MAP.

b. Явное (динамическое) подключение.В этом случае загрузка (а также и выгрузка)DLL-библиотеки осуществляется программой по мере необходимости. Воспользуйтесь созданной в предыдущем задании динамической библиотекойDLL.DLL. Создайте новый проект для подготовки вызывающей программы с именем, например,CPP2.IDE.Не включайтев него библиотеку импорта.Не включайтев него прототипы вызываемых функций. Алгоритм программыCPP2.CPPдолжен содержать следующие элементы:

  • вывод в окно сообщения информации о запуске программы;

  • загрузка динамической библиотеки DLL.DLLвызовом функции WindowsLoadLibrary()с сохранением полученного дескриптора;

  • получение адресов вызываемых из DLL-библиотеки функций с помощью функции WindowsGetProcAddress(). В качестве первого параметра этой функции следует указывать полученный ранее дескриптор загруженной библиотеки, а в качестве второго параметра – найденные в предыдущем задании “декорированные” имена вызываемых функций;

  • последовательный вызов обеих функций из DLL-библиотеки посредством полученных на предыдущем этапе адресов;

  • выгрузка библиотеки вызовом функции FreeLibrary().

Откомпилируйте программу CPP.EXE. Запустив программу на выполнение, убедитесь, что внешне она работает так же, как и предыдущая, хотя, возможно, вам удастся заметить задержку при ее выполнении на этапе поиска и загрузкиDLL-библиотеки.

c. Динамическая загрузка с исходными именами вызываемых функций. Поскольку в этом заданииDLL-библиотеку следует создавать не так, как в предыдущих заданиях, откройте новый проект для создания приложения типаDynamicLibrary(.dll). Пусть этот проект носит имя DLL3.IDE. Включите в него имеющийся уже у вас исходный файл DLL3.CPPи, кроме того, файл определения модуля с именемDLL3.DEF. Этот файл будет состоять из трех строк (при наличии вDLL-библиотеке двух функций):

EXPORTS

имя_функции1_в_программе = декорированное_имя_функции

имя_функции2_в_программе = декорированное_имя_функции

Заново скомпилируйте DLL-библиотеку.

Создайте новый проект для подготовки вызывающей программы (CPP3.IDE). Скопируйте файлCPP2.CPPпод именемCPP3.CPPи исправьте в нем имя загружаемойDLL-библиотеки на новое. Исправьте также “декорированные” имена вызываемых функций на те, которые использовались в исходном файлеDLL-библиотеки. Получите загрузочный модуль основной программы и убедитесь в правильности его работы.