Студопедия — Создание динамических библиотек
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Создание динамических библиотек






Динамические библиотеки представляют собой хранилище общедоступных процедур. Использование динамических библиотек (по-другому - библиотек динамической компоновки) - это способ осуществления модульности в период выполнения программы. Динамическая библиотека (Dynamic Link Library - DLL) позволяет упростить и саму разработку программного обеспечения.В процессе компоновки испольняемого модуля с использованием внешних процедур в него помещаются не сами процедуры, а их нзвания или имена (в зависимости от версии ОС), поэтому вместо того, чтобы каждый раз перекомпилировать огромные ЕХЕ-программы, достаточно перекомпилировать лишь отдельный динамический модуль. Кроме того, доступ к динамической библиотеке возможен сразу из нескольких исполняемых модулей, что делает многозадачность более гибкой. Структура DLL-модуля подобна структуре ЕХЕ-модуля. По своей функциональности динамическая библиотека очень похожа на оверлей, но название " динамическая библиотека" более удачно.

При создании динамической библиотеки необходимо указать импортируемые и экспортируемые функции.

Чтобы лучшего понимания DLL поясним варианты связывания при работе линковщика (редактора связей). Во время трансляции связываются имена, указанные в программе как внешние, (EXTERN) с соответствующими именами из библиотек, которые указываются при помощи директивы IMPORTLIB. Такое связывание называется ранним (или статическим). Напротив, в случае с динамической библиотекой связывание происходит во время выполнения модуля. Такое связывание называется поздним (или динамическим). При этом позднее связывание может происходить в автоматическом режиме в начале запуска программы и при помощи специальных API-функций (см. ниже), по желанию программиста. Познее связывание может быть явным или неявным. Сказанное иллюстрирует рис. 13. Заметим также, что использование динамической библиотеки экономит дисковое пространство, т.к. представленная в библиотеке процедура содержится лишь один раз, в отличие от процедур, помещаемых в модули из статических библиотек43.

В среде Windows используются два механизма связывания: по символьным именам и по порядковым номерам. В первом случае функция, определенная в динамической библиотеке, идентифицируется по ее имени, во втором - по порядковому номеру, который должен быть задан при трансляции (используется в современных ОС Windows).

 

Рис. 13. Иллюстрация понятия связывания в ассемблере.

Динамическая библиотека может содержать также ресурсы. Так, файлы шрифтов представляют собой динамические библиотеки, единственным содержимым которых являются ресурсы.

Динамическая загружается в адресное пространство процесса, поэтому данные процесса доступны из динамической библиотеки, и, наоборот, данные динамической библиотеки доступны для процесса.

В любой динамической библиотеке следует определить точку входа (процедура входа). По умолчанию за точку входа принимают метку, указываемую за директивой END (например, END START). При загрузке динамической библиотеки и выгрузке динамической библиотеки автоматически вызывается процедура входа. Заметим при этом, что каким бы способом ни была загружена динамическая библиотека (явно или неявно), выгрузка динамической библиотеки из памяти будет происходить автоматически при закрытии процесса или потока. В принципе, процедура входа может быть использована для некоторой начальной инициализации переменных. Довольно часто эта процедура остается пустой. При вызове процедуры входа в нее помещаются три параметра:

· 1-й параметр. Идентификатор DLL-модуля.

· 2-й параметр. Причина вызова (см. ниже).

· 3-й параметр. Резерв.

Рассмотрим подробнее второй параметр процедуры входа. Вот четыре возможных значения этого параметра:

DLL_PROCESS_DETACH equ 0DLL_PROCESS_ATTACH equ 1DLL_THREAD_ATTACH equ 2DLL_THREAD_DETACH equ 3

DLL_PROCESS_ATTACH - сообщает, что динамическая библиотека загружена в адресное пространство вызывающего процесса.

DLL_THREAD_ATTACH - сообщает, что Текущий процесс создает новый поток. Такое сообщение посылается всем динамическим библиотекам, загруженным к этому времени процессом.

DLL_PROCESS_DETACH - сообщает, что динамическая библиотека выгружается из адресного пространства процесса.

DLL_THREAD_DETACH - сообщает, что некий поток, созданный данным процессом, в адресное пространство которого загружена данная динамическая библиотека, уничтожается.

Приведем пример простейшей динамической библиотеки. Данная динамическая библиотека, по сути, ничего не делает. Просто при загрузке библиотеки, ее выгрузки, а также вызове процедуры DLLP1 будет вызвано обычное Windows-сообщение. Обратите внимание, как определяется процесс загрузки и выгрузки библиотеки. Заметим также, что процедура входа должна возвращать ненулевое значение. Процедура DLLP1 обрабатывает также один параметр, передаваемый через стек обычным способом.

.386; плоская модель.MODEL FLAT, stdcall PUBLIC DLLP1; константы; сообщения, приходящие при открытии; динамической библиотеки DLL_PROCESS_DETACH equ 0DLL_PROCESS_ATTACH equ 1DLL_THREAD_ATTACH equ 2DLL_THREAD_DETACH equ 3 EXTERN MessageBoxA@16: NEAR includelib user32.lib includelib kernel32.lib; сегмент данных_DATA SEGMENT DWORD PUBLIC USE32 'DATA' TEXT1 DB 'Вход в библиотеку', 0 TEXT2 DB 'Выход из библиотеки', 0 MS DB 'Сообщение из библиотеки', 0 TEXT DB 'Вызов процедуры из DLL', 0_DATA ENDS; сегмент кода_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'; [EBP+10H]; резервный параметр; [EBP+0CH]; причина вызова; [EBP+8]; идентификатор DLL-модуляDLLENTRY: MOV EAX, DWORD PTR [EBP+0CH] CMP EAX, 0 JNE D1; закрытие библиотеки PUSH 0 PUSH OFFSET MS PUSH OFFSET TEXT2 PUSH 0 CALL MessageBoxA@16 JMP _EXITD1: CMP EAX, 1 JNE _EXIT; открытие библиотеки PUSH 0 PUSH OFFSET MS PUSH OFFSET TEXT1 PUSH 0 CALL MessageBoxA@16_EXIT: MOV EAX, 1 RET 12; ———————————————————; [EBP+8]; параметр процедурыDLLP1 PROC EXPORT PUSH EBP MOV EBP, ESP CMP DWORD PTR [EBP+8], 1 JNE _EX PUSH 0 PUSH OFFSET MS PUSH OFFSET TEXT PUSH 0 CALL MessageBoxA@16_EX: POP EBP RET 4DLLP1 ENDP_TEXT ENDSEND DLLENTRY

Программа может быть оттранслирована как с помощью MASM32.

Обратите внимание, что за процедурой, вызываемой из другого модуля, указано ключевое слово EXPORT. Это слово необходимо для правильной трансляции в MASM.

Трансляция динамической библиотеки в MASM32может быть выполнена следующим образом.

ml /c /coff /DMASM dll1.asm link /subsystem: windows /DLL /ENTRY: DLLENTRY dll1.obj

 

Ниже представлена программа, которая загружает созданную динамическую библиотеку. Это пример позднего связывания. Библиотека должна быть вначале загружена при помощи функции LoadLibrary. Затем определяется адрес процедуры с помощью функции GetProcAddress, после чего можно осуществлять вызов. Как и следовало ожидать, MASM помещает в динамическую библиотеку вместо DLLP1 имя _DLLP1@0.

В программе учтена возможность ошибки при вызове функций LoadLibrary и GetProcAddress. В этой связи укажем, как (в какой последовательности) ищет библиотеку функция LoadLibrary:

1. Поиск в каталоге, откуда была запущена программа.

2. Поиск в текущем каталоге.

3. В системном директории (GetSystemDirectory).

4. В директории Windows (GetWindowsDirectory).

5. В каталогах, указанных в окружении (PATH).

В конце программы динамическая библиотека выгружается из памяти. Отметим, что по выходе из программы эта процедура выполняется автоматически.

.386; плоская модель.MODEL FLAT, stdcall; константы; прототипы внешних процедур; MASM EXTERN GetProcAddress@8: NEAR EXTERN LoadLibraryA@4: NEAR EXTERN FreeLibrary@4: NEAR EXTERN ExitProcess@4: NEAR EXTERN MessageBoxA@16: NEAR; директивы компоновщику для подключения библиотек includelib user32.lib includelib kernel32.lib; сегмент данных_DATA SEGMENT DWORD PUBLIC USE32 'DATA' TXT DB 'Ошибка динамической библиотеки', 0 MS DB 'Сообщение', 0 LIBR DB 'DLL.DLL', 0 HLIB DD? NAMEPROC DB '_DLLP1@0', 0_DATA ENDS; сегмент кода_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'START:; загрузить библиотеку PUSH OFFSET LIBR CALL LoadLibraryA@4 CMP EAX, 0 JE _ERR MOV HLIB, EAX; получить адрес процедуры PUSH OFFSET NAMEPROC PUSH HLIB CALL GetProcAddress@8 CMP EAX, 0 JNE YES_NAME; сообщение об ошибке_ERR: PUSH 0 PUSH OFFSET MS PUSH OFFSET TXT PUSH 0 CALL MessageBoxA@16 JMP _EXITYES_NAME: PUSH 1; параметр CALL EAX; закрыть библиотеку PUSH HLIB CALL FreeLibrary@4; библиотека автоматически закрывается также; при выходе из программы; выход_EXIT: PUSH 0 CALL ExitProcess@4_TEXT ENDSEND START

Результат выполнения программы: Сообщение о вызове

Трансляция программы на Рис. 3.3.3 ничем не отличается от трансляции обычных программ.

MASM32.

ml /c /coff /DMASM dllex.asm link /subsystem: windows dllex.obj

С примерами использования неявного связывания можно ознакомиться в [ Пирогов].

Как правило, различные экземпляры приложения или разные процессы в ОС используют динамическую библиотеку, загружая ее в собственное адресное пространство. С точки зрения использования оперативной памяти это не рационально, однако, лучше с точки зрения надежности выполнения процессов. В ряде случаев приложение может инициализировать так называемую разделяемую память. Это происходит следующим образом. Запускаемое приложение загружает динамическую библиотеку и вызывает процедуру из динамической библиотеки, которая меняет данные, также расположенные в динамической библиотеке. Запустим теперь второй экземпляр приложения. Оно загружает еще один экземпляр динамической библиотеки. Могут быть ситуации, когда желательно, чтобы второе запущенное приложение " знало", что по команде первого приложения данные уже изменились. В этом случае данные, которыми оперирует динамическая библиотека, должны быть общими. Сделать их таковыми можно указанием опции редактора связей LINK /section: имя, атрибуты, которая позволяет объявить явно свойства данной секции (сегмент данных)

Приведем пример возможности использования разделяемой памяти. Перед выходом из процедуры динамической библиотеки изменяется строка, хранящаяся в разделяемой секции памяти. При этом приложение не заканчивает своей работы. При запуске второго экземпляра приложения на экран выводится уже измененное первым приложением значение строки.

; динамическая библиотека DLL4.ASM.386P; плоская модель.MODEL FLAT, stdcall PUBLIC DLLP1; MASM; прототипы внешних процедур EXTERN MessageBoxA@16: NEAR; директивы компоновщику для подключения библиотек includelib user32.lib includelib kernel32.lib; сегмент данных_DATA SEGMENT DWORD PUBLIC USE32 'DATA' TEXT DB " В динамической библиотеке", 0 MS DB " Сообщение", 0_DATA ENDS; сегмент кода_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'; [EBP+10H]; резервный параметр; [EBP+0CH]; причина вызова; [EBP+8]; идентификатор DLL-модуляDLLENTRY: MOV EAX, 1 RET 12; ------------------; адреса параметровDLLP1 PROC EXPORT PUSH EBP MOV EBP, ESP PUSH 0 PUSH OFFSET MS PUSH OFFSET TEXT PUSH 0 CALL MessageBoxA@16; изменим строку, расположенную в разделяемой памяти MOV TEXT, 'И' MOV TEXT+1, 'з' POP EBP RETDLLP1 ENDP_TEXT ENDSEND DLLENTRY; основной модуль DLLEX4.ASM, вызывающий; процедуру из динамической библиотеки .386P; плоская модель.MODEL FLAT, stdcall; константы; прототипы внешних процедур; MASM EXTERN GetProcAddress@8: NEAR EXTERN LoadLibraryA@4: NEAR EXTERN FreeLibrary@4: NEAR EXTERN ExitProcess@4: NEAR EXTERN MessageBoxA@16: NEAR; директивы компоновщику для подключения библиотек includelib user32.lib includelib kernel32.lib; сегмент данных_DATA SEGMENT DWORD PUBLIC USE32 'DATA' TXT DB 'Ошибка динамической библиотеки', 0 MS DB 'Сообщение', 0 LIBR DB 'DLL4.DLL', 0 HLIB DD? NAMEPROC DB '_DLLP1@0', 0_DATA ENDS; сегмент кода_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'; [EBP+10H]; резервный параметр; [EBP+0CH]; причина вызова; [EBP+8]; идентификатор DLL-модуляSTART:; загрузить библиотеку PUSH OFFSET LIBR CALL LoadLibraryA@4 CMP EAX, 0 JE _ERR MOV HLIB, EAX; получить адрес PUSH OFFSET NAMEPROC PUSH HLIB CALL GetProcAddress@8 CMP EAX, 0 JNE YES_NAME; сообщение об ошибке_ERR: PUSH 0 PUSH OFFSET MS PUSH OFFSET TXT PUSH 0 CALL MessageBoxA@16 JMP _EXITYES_NAME: CALL EAX PUSH 0 PUSH OFFSET MS PUSH OFFSET MS PUSH 0 CALL MessageBoxA@16; закрыть библиотеку; библиотека автоматически закрывается также; при выходе из программы PUSH OFFSET NAMEPROC PUSH HLIB CALL FreeLibrary@4; выход_EXIT: PUSH 0 CALL ExitProcess@4_TEXT ENDSEND START

Для трансляции и компоновки программ следует указать опцию /section

ml /c /coff /DMASM dll4.asm link /subsystem: windows /DLL /section:.data, SRW dll4.obj ml /c /coff /DMASM dllex4.asm link /subsystem: windows dllex4.obj

Атрибуты опции SECTION: S-SHARED, R-READ, W-WRITE.

Пример: Написать программу на ассемблер. Задан массив А из N = 40 элементов. Навести алгоритм и программу определения количества элементов массива А, которые удовлетворяют условию L > = Ai > = M, где L = 6 и M = 22.

Текст программы:
файл 1111.asm

.386







Дата добавления: 2014-11-10; просмотров: 1235. Нарушение авторских прав; Мы поможем в написании вашей работы!



Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Способы тактических действий при проведении специальных операций Специальные операции проводятся с применением следующих основных тактических способов действий: охрана...

Искусство подбора персонала. Как оценить человека за час Искусство подбора персонала. Как оценить человека за час...

Этапы творческого процесса в изобразительной деятельности По мнению многих авторов, возникновение творческого начала в детской художественной практике носит такой же поэтапный характер, как и процесс творчества у мастеров искусства...

ПРОФЕССИОНАЛЬНОЕ САМОВОСПИТАНИЕ И САМООБРАЗОВАНИЕ ПЕДАГОГА Воспитывать сегодня подрастающее поколение на со­временном уровне требований общества нельзя без по­стоянного обновления и обогащения своего профессио­нального педагогического потенциала...

Эффективность управления. Общие понятия о сущности и критериях эффективности. Эффективность управления – это экономическая категория, отражающая вклад управленческой деятельности в конечный результат работы организации...

Мотивационная сфера личности, ее структура. Потребности и мотивы. Потребности и мотивы, их роль в организации деятельности...

Studopedia.info - Студопедия - 2014-2024 год . (0.042 сек.) русская версия | украинская версия