Разработка динамических (DLL) библиотек Стрельба в цель упражняет руку и причиняет верность глазу. Динамические подключаемые библиотеки (Dynamic Link Libraries, DLLs) являются хранилищем общедоступных процедур. Механизм DLL-библиотек появился вместе с операционной системой Windows и является ее неотъемлемой частью. Суть этого механизма в том, что в процессе компоновки исполняемого модуля с использованием внешних процедур в него помещаются не сами процедуры, а только их названия (номера) вместе с названиями DLL-библиотек, в которых они содержится. В уроке 14 «Модульное программирование» учебника для связи модулей на разных языках рассматривались стандартные соглашения по передаче параметров, которые специфическим образом реализовывались на уровне конкретных компиляторов языков программирования. Этот механизм был, пожалуй, единственным средством связи разноязыковых модулей при программировании для MS DOS. В среде Windows более естественным является механизм DLL-библиотек. Он позволяет, в частности, разработать набор процедур на ассемблере и затем использовать их в программах на языках высокого уровня, поддерживающих механизм динамического связывания. Шаг 1. Разработка текста DLL-библиотеки Как мы уже отметили, DLL-библиотека представляет собой обычную программу на языке ассемблера. Выбор примера для демонстрации разработки и использования DLL-библиотеки неслучаен. Тем самым мы подтвердим тезис о том, что обычная программа и DLL-библиотека имеют много общего. С точки зрения структуры DLL-библиотека является набором функций, переменных и констант, а также необязательного кода инициализации, которые оформлены в соответствии с требованиями ассемблера. Ниже приведен пример DLL-библиотеки для нашей задачи. ;maket_dll.asm - текст DLL-библиотеки. :Содержит одну функцию - WriteCon Хорошо видно, что DLL-библиотека является действительно обычным файлом ассемблера. Есть все, даже имя точки входа, указываемое в последней директиве END. Но здесь и начинаются странности. На самом деле это не обычная точка входа, которую мы привыкли указывать в любой программе на ассемблере, а адрес команды в DLL-библиотеке, получающей управление в строго определенных случаях. Эта команда является первой в цепочке команд, составляющих так называемый код инициализации DLL-библиотеки. Назначение этого кода — выполнить необходимые действия по инициализации DLL-библиотеки при наступлении определенных событий. Наличие этого кода в DLL-библиотеке необязательно, и при его отсутствии нет необходимости указывать соответствующую метку в заключительной директиве END. Если все же код инициализации присутствует в DLL-библиотеке, то он должен быть разработан с учетом определенных требований.
Структура полного варианта инициализациониого кода выглядит так: includeWindowConA.inc;проверьте присутствие значений флагов в этом файле" Минимальный вариант может выглядеть так, как это сделано в нашем примере: DllMain ргос Или так: DllMain: m: moveax.l ret 12 He забывайте, что директива arg приводит к тому, что в код, генерируемый транслятором, вставляются команды ENTERD и LEAVED (см. выше разделы «Реализация рекурсивных процедур» и «Реализация вложенных процедур»). Кроме этого, команда RET процедуры дополняется значением, равным сумме длин параметров, указанных в директиве ARG . Исполнение такой команды приводит к удалению из стека количества байт, равного этому сформированному значению. Шаг 2. Трансляция и компоновка исходного текста DLL-библиотеки После того как подготовлен исходный текст библиотеки, его транслируют обычным для программ ассемблера образом. Что же касается компоновки, то необходимо помнить, что ее целью является получение файла с расширением .dll, а не обычного файла с расширением .ехе. Весь этот процесс удобно обсуждать на примере реального файла makefile, текст которого приведен ниже: TASM0PT=/m3 /mx /z /q /DWINVER=0400 /D_WIN32_WINNT=0400 Запуск данного файла производится командной строкой: make -DOEBUG -fmakefile_dll.mak >p.txt В результате формируется несколько файлов, перечень которых определяется тем, насколько успешно отработали программы транслятора tasm32 и компоновщика nk.32. Для быстрой оценки этого результата мы перенаправили весь вывод в файл p.txt Просмотрев этот файл, можно оценить успешность создания DLL-библиотеки, не анализируя другие файлы (например, файл листинга). При наличии синтаксических ошибок необходимо исправить их и повторить запуск make-файла на исполнение. LIBRARY maketjll DESCRIPTION 'Win32 DLL' EXPORTS WriteCon @1 В этом файле следует обратить внимание на директиву EXPORTS, которая содержит имена экспортируемых функций DLL-библиотеки и их ординалы, то есть порядковые номера этих функций в DLL-библиотеке. Последние использовались в 16-разрядных версиях Windows, однако в современных версиях этой операционной системы их использование необязательно, и Microsoft настоятельно рекомендует этого не делать. Шаг 3. Создание lib-файла Как указать приложению местонахождение внешних функций, расположенных в DLL-библиотеках? Если бы приложение использовало только одну DLL-библиотеку, то проблем бы не было — указывай нужную и продолжай процесс сборки приложения. Если количество необходимых приложению DLL-библиотек больше одной, а тем более если их десятки, то ситуация требует иного решения, нежели простое перечисление нужных приложению DLL-библиотек. Для централизованного хранения информации о размещении используемых приложением функций в DLL-библиотеках применяют LIB-файлы. Эти файлы представляют собой своеобразный справочник о размещении функций в DLL-библиотеках. При этом не указывается никаких путей, так как при обращении к DLL-библиотеке операционная система ищет ее по следующему алгоритму.
В пакете TASM для создания LIB-файла предназначена утилита Implib.exe. Для создания LIB-файла в нашем примере необходимо выполнить следующую командную строку: IMPLIB.EXE maketjll .lib maket_dll.DLL >p.txt Как видите, мы опять используем перенаправление вывода в файл p.txt для быстрой оценки результата работы программы IMPLIB.EXE. Если выполнение этой утилиты было успешным, то формируется файл maket_dll.lib, который в дальнейшем используется для сборки целевого приложения. Шаг 4. Сборка приложения с использованием DLL-библиотеки Приведем содержимое make-файла для сборки целевого приложения: NAME = maket Теперь, имея два make-файла (для сборки файлов .dll и .ехе ), можно провести сравнительный анализ их содержимого. Отметим два момента: NAME maket И наконец, содержимое самого файла maket.asm, использующего функцию из разработанной нами DLL-библиотеки maket_dll.dll. : maket.asm - программа, вызывающая функцию WriteCon из файла maket_dll.dll Импортируемую из DLL-библиотеки функцию необходимо объявить внешней директивой extrn WriteCon:PROC. Шаг 5. Проверка работоспособности приложения с использованием DLL-библиотеки Для проверки работоспособности полученного на предыдущем шаге приложения можно использовать отладчик TD32.EXE. Кстати, когда вы будете в нем работать, обратите внимание на то, как происходит переход из DLL-библиотеки на код в процедуре. Вы увидите, что помощь в этом оказывает неизвестно откуда появившаяся команда JMP. Причину этого вы можете выяснить, прочитав раздел «Секция описания импортируемых функций РЕ-файла» главы «Форматы исполняемых файлов» книги. DUMPBIN.EXE -exports maketjJll.DLL>p.txt Тогда в файле p.txt вы получите отчет о содержимом раздела экспорта DLL-библиотеки maket_dll.dll. Проанализировав полученные результаты, вы убедитесь, что проблем с распознаванием нашей DLL-библиотеки у этого программного средства фирмы Microsoft не возникло. Это дает основание полагать, что данную библиотеку при соответствующем наполнении полезными функциями можно использовать при программировании на VisualC/C++, VisualBasic и т. п. При этом необходимо иметь в виду, что может иметь место искажение имен функций при использовании компиляторов различных фирм. Подробнее об этом можно узнать в соответствующей литературе. HINSTANCE LoadLibraryC LPCTSTR lpLibFileName ): Третий способ загрузки DLL-библиотек — отложенная загрузка. Этот вид загрузки предполагает, что DLL-библиотека не будет загружена в адресное пространство процесса до тех пор, пока приложению не потребуется осуществить доступ к любому экспортируемому из этой DLL-библиотеки объекту (переменной, константе, процедуре). Подробнее об этом и других вопросах разработки и использования DLL-библиотек можно прочитать в литературе. |
Copyright © 2010-2011 | ||
---|---|---|
Хостинг : Narod.Yandex.ru | Соглашение | e-mail : softcreate@pochta.ru |