Создание динамических библиотек
Сущность DLL как динамических библиотек, позволяющих многократное использование различных программных приложений. Характеристика двух механизмов связывания в среде Windows. Описание функций LoadIcon, LoadLibrary, PostMessage, ExitProcess, их параметры.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 10.02.2015 |
Размер файла | 331,7 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru
Содержание
Введение
1. Теоретическая часть
2. Описание функций
3. Реализация на примерах
Выводы
Список литературы
Введение
DLL (англ. Dynamic Link Library -- «библиотека динамической компоновки», «динамически подключаемая библиотека») (Расширение приложения) в операционных системах Microsoft Windows и IBM OS/2 -- динамическая библиотека, позволяющая многократное использование различными программными приложениями. K DLL относятся также элементы управления ActiveX и драйверы.
В мире UNIX аналогичные функции выполняют так называемые общие объекты (англ. shared objects).
Формат файлов DLL придерживается тех же соглашений, что и формат исполняемых файлов, сочетая код, таблицы и ресурсы, отличаясь лишь интерпретацией некоторых полей.
Использование динамических библиотек (по-другому - библиотек динамической компоновки) - это способ осуществления модульности в период выполнения программы. Динамическая позволяет упростить и саму разработку программного обеспечения. Вместо того чтобы каждый раз перекомпилировать огромные ЕХЕ-программы, достаточно перекомпилировать лишь отдельный динамический модуль. Кроме того, доступ к динамической библиотеке возможен сразу из нескольких исполняемых модулей, что делает многозадачность более гибкой. Фактически, полных преимуществ от внедрения динамически подключаемых библиотек получить не удалось по причине явления, называемого DLL hell («DLL ад»).
DLL hell возникает, когда несколько приложений требуют одновременно различные, не полностью совместимые, версии библиотек, что приводит к сбоям в этих приложениях и к конфликтам типа DLL hell, резко снижая общую надёжность операционных систем. Поздние версии Microsoft Windows стали разрешать параллельное использование разных версий DLL (технология Side-by-side assembly), что свело на нет преимущества изначального принципа модульности.
1. Теоретическая часть
Во время трансляции связываются имена, указанные в программе как внешние, (EXTERN) с соответствующими именами из библиотек, которые указываются при помощи директивы IMPORTLIB. Такое связывание называется ранним (или статическим). Напротив, в случае с динамической библиотекой связывание происходит во время выполнения модуля. Такое связывание называется поздним (или динамическим). При этом позднее связывание может происходить в автоматическом режиме в начале запуска программы и при помощи специальных API-функций, по желанию программиста. При этом говорят о явном и неявном связывании.
В среде Windows практикуются два механизма связывания: по символьным именам и по порядковым номерам. В первом случае функция, определенная в динамической библиотеке, идентифицируется по ее имени, во втором - по порядковому номеру, который должен быть задан при трансляции. Связывание по порядковому номеру в основном практиковалось в старой операционной системе Windows З.х., связывание по имени - более удобный механизм.
Рис. 1 Общая структура
Динамическая библиотека может содержать также ресурсы. Так, файлы шрифтов представляют собой динамические библиотеки, единственным содержимым которых являются ресурсы. Должно сказать, что динамическая библиотека как бы становится продолжением Вашей программы, загружаясь в адресное пространство процесса. Соответственно, данные процесса доступны из динамической библиотеки, и, наоборот, данные динамической библиотеки доступны для процесса.
В любой динамической библиотеке следует определить точку входа (процедура входа). По умолчанию за точку входа принимают метку, указываемую за директивой END (например, END START). При загрузке динамической библиотеки и выгрузке динамической библиотеки автоматически вызывается процедура входа. Заметим при этом, что каким бы способом ни была загружена динамическая библиотека (явно или неявно), выгрузка динамической библиотеки из памяти будет происходить автоматически при закрытии процесса или потока. В принципе, процедура входа может быть использована для некоторой начальной инициализации переменных. Довольно часто эта процедура остается пустой. При вызове процедуры входа в нее помещаются три параметра:
1-й параметр. Идентификатор DLL-модуля.
2-й параметр. Причина вызова.
3-й параметр. Резерв.
Рассмотрим подробнее второй параметр процедуры входа. Вот четыре возможных значения этого параметра:
DLL_PROCESS_DETACH equ 0
DLL_PROCESS_ATTACH equ 1
DLL_THREAD_ATTACH equ 2
DLL_THREAD_DETACH equ 3
DLL_PROCESS_ATTACH - сообщает, что динамическая библиотека загружена в адресное пространство вызывающего процесса.
DLL_THREAD_ATTACH - сообщает, что Текущий процесс создает новый поток. Такое сообщение посылается всем динамическим библиотекам, загруженным к этому времени процессом.
DLL_PROCESS_DETACH - сообщает, что динамическая библиотека выгружается из адресного пространства процесса.
DLL_THREAD_DETACH - сообщает, что некий поток, созданный данным процессом, в адресное пространство которого загружена данная динамическая библиотека, уничтожается.
Формат DLL-библиотеки почти идентичен формату загрузочного модуля приложения Windows, однако вы не можете "запустить" DLL-библиотеку на выполнение, как обычное приложение. И это понятно, так как назначение DLL-библиотек другое - они служат хранилищем функций, вызываемых приложениями во время работы. Функции, расположенные в DLL-библиотеках, могут вызывать функции, которые находятся в других библиотеках.
DLL-библиотека также является модулем. Она находится в памяти в единственном экземпляре, содержит сегменты кода и ресурсы, а так же один сегмент данных. Можно сказать, что для DLL-библиотеки создается одна копия (instance), состоящая только из сегмента данных, и один модуль, состоящий из кода и ресурсов.
Тем не менее, функции, расположенные в DLL-библиотеке, пользуются сегментом данных, принадлежащей этой библиотеке, а не копии приложения. При этом возникают трудности, связанные с тем, что сегментный регистр SS, с помощью которого адресуется стек, указывает на стек копии приложения, а регистр DS - на сегмент данных DLL-библиотеки.
Для чего используются DLL-библиотеки? Прежде всего для экономии памяти, так как все запущенные приложения могут использовать один модуль DLL-библиотеки, не включая стандартные функции в состав своих модулей.
С помощью DLL-библиотек можно организовать коллективное использование ресурсов или данных, расположенных в сегменте данных библиотеки. Более того, вы можете создать DLL-библиотеки, состоящие только из одних ресурсов, например, из пиктограмм или изображений bitmap. В состав Windows входит DLL-библиотека moricons.dll, состоящая из одних пиктограмм. Файлы с расширением .fon представляют собой ни что иное, как DLL-библиотеки, содержащие шрифты в виде ресурса.
программный библиотека windows
2. Описание функций
Функция LoadIcon
function LoadIcon(Instance: THandle; IconName: PChar): HIcon;
Загpужает поименованный pесуpс пиктогpаммы.
Паpаметpы:
Instance: Экземпляp модуля, исполнимый файл котоpого содеpжит пиктогpамму или 0 для пpедопpеделенной пиктогpаммы.
IconName: Стpока или имя целочисленного идентификатоpа или пpедопpеделенная пиктогpамма, опpеделенная одной из констант idi. Возвpащаемое значение:
В случае успешного завеpшения - идентификатоp пиктогpаммы; 0 - в пpотивном случае.
функция находится в файле user32.dll
Функция LoadLibrary
function LoadLibrary(LibFileName: PChar): THandle;
Загpужает поименованный модуль библиотеки.
Паpаметpы:
LibFileName: Имя файла библиотеки (заканчивающееся пустым символом).
Возвpащаемое значение:
В случае успешного завеpшения - идентификатоp экземпляpа модуля библиотеки (значение, больше 32); если нет, то его значение меньше 32 и является одним из следующих: (0) нет памяти;
(5) попытка связать задачу; (11) невеpный файл EXE; (12) пpикладная задача из OS/2; (13) пpикладная задача из DOS 4.0; (14) невеpный тип EXE; (15) незащищенный pежим.
функция находится в файле kernel32.dll
Функция PostMessage
function PostMessage(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Bool;
Напpавляет сообщение окну пpикладной задачи.
Паpаметpы:
Wnd: Окно, котоpое будет пpинимать сообщение, или $FFFF для всех пеpекpываемых или всплывающих окон.
Msg: Тип сообщения.
wParam: Дополнительная инфоpмация о сообщении.
lParam: Дополнительная инфоpмация о сообщении.
Возвpащаемое значение:
Не нуль в случае успешного завеpшения; 0 - если нет.
функция находится в файле user32.dll
Функция GetModuleHandle
function GetModuleHandle(ModuleName: PChar): THandle;
Считывает описатель модуля.
Паpаметpы:
ModuleName: Имя модуля (заканчивающееся пустым символом).
Возвpащаемое значение:
В случае успешного завеpшения - идентификатоp модуля; 0 - в пpотивном случае.
функция находится в файле kernel32.dll
Функция DialogBoxParam
function DialogBoxParam(Instance, THandle; TemplateName: PChar; Parent: HWnd; DialogFunc: TFarProc; InitParam: Longint): Integer;
Создает блок модального диалога, опpеделенного TemplateName, и пеpед тем, как отобpажать диалог, посылает сообщение wm_InitDialog. Также позволяет пеpедавать функции обpатного вызова начального паpаметpа.
Паpаметpы:
Instance: Экземпляp модуля, исполнимый файл котоpого содеpжит шаблон блока диалога.
TemplateName: Имя шаблона блока диалога (заканчивающееся пустым символом).
Parent: Окно владельца.
DialogFunc: Адpес экземпляpа пpоцедуpы функции диалога.
InitParam: Пеpедается в паpаметpе lParam сообщения wm_InitDialog.
Возвpащаемое значение:
Паpаметp nResult функции EndDialog; -1 - если диалог не может быть создан.
функция находится в файле user32.dll
Функция ExitProcess
function ExitProcess (uExitCode);
Закончить данный процесс со всеми подзадачами (потоками).
Параметры:
uExitCode Определяет код выхода для процесса, и для всех потоков, которые завершают работу в результате вызова этой функции.
Возвpащаемое значение:
У этой функции нет возвращаемого значения
Функция FreeLibrary
function FreeLibrary(LibModule: THandle);
Делает недействительным LibModule и освобождает связанную с ним память, если модуль больше не адpесуется.
Паpаметpы:
LibModule: Загpуженный библиотечный модуль.
функция находится в файле kernel32.dll
Функция EndDialog
function EndDialog(Dlg: Hwnd; Result: Integer);
Теpминиpует модальный блок диалога. Значение, указанное паpаметpом Result, возвpащается в создающую функцию DialogBox.
Паpаметpы:
Dlg: Уничтожаемый диалог.
Result: Возвpащаемое значение.
функция находится в файле user32.dll
Функция GetProcAddress
function GetProcAddress(Module: THandle; ProcName: PChar): TFarProc;
Считывает адpес экспоpтиpованной библиотечной функции.
Паpаметpы:
Module: Библиотечный модуль.
ProcName: Имя функции (заканчивающееся пустым символом) или пpоизвольное значение.
Возвpащаемое значение:
В случае успешного завеpшения - точка входа в функцию; 0 - в пpотивном случае.
функция находится в файле kernel32.dll
Функция MessageBox
function MessageBox(Parent: HWnd; Txt, Caption: PChar; TextType: Word): Integer;
Создает и отобpажает блок диалога, содеpжащий указанное сообщение и заголовок, а также пpедопpеделенные пиктогpаммы и текстовые кнопки, в соответствии с паpаметpом TexType.
Паpаметpы:
Parent: Окно, владеющее блоком сообщений.
Txt: Отобpажаемое сообщение (заканчивающееся пустым символом).
Caption: Заголовок блока диалога (заканчивающийся пустым символом) или nil для "Error" ("Ошибка").
TextType: Одна или комбинация констант mb.
Возвpащаемое значение:
В случае успешного завеpшения одна из следующих констант: id_Abort, id_Cancel, id_Ignore, id_No, id_OK, id_Retry или id_Yes.
функция находится в файле user32.dll
3. Реализация на примерах
Простейшая библиотека
Данная динамическая библиотека, по сути, ничего не делает. Просто при загрузке библиотеки, ее выгрузки, а также вызове процедуры DLLP1 будет вызвано обычное Windows-сообщение. Процедура входа должна возвращать ненулевое значение. Процедура DLLP1 обрабатывает также один параметр, передаваемый через стек обычным способом.
1.bat:
C:\masm32\bin\ml.exe /c /coff /DMASM dll1.asm
C:\masm32\bin\link.exe /subsystem:windows /DLL dll1.obj
pause 0
dll1.asm:
.386P
; плоская модель
IFDEF MASM
.MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF
PUBLIC DLLP1
; константы
; сообщения, приходящие при открытии
; динамической библиотеки
DLL_PROCESS_DETACH equ 0
DLL_PROCESS_ATTACH equ 1
DLL_THREAD_ATTACH equ 2
DLL_THREAD_DETACH equ 3
IFDEF MASM
; MASM
; прототипы внешних процедур
EXTERN MessageBoxA@16:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
EXTERN MessageBoxA:NEAR
MessageBoxA@16 = MessageBoxA
includelib c:\tasm\lib\import32.lib
ENDIF
;--------------------------------------------------
; сегмент данных
_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 _EXIT
D1:
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 4
DLLP1 ENDP
_TEXT ENDS
END DLLENTRY
Явное связывание
Библиотека должна быть вначале загружена при помощи функции LoadLibrary. Затем определяется адрес процедуры с помощью функции GetProcAddress, после чего можно осуществлять вызов. Как и следовало ожидать, MASM помещает в динамическую библиотеку вместо DLLP1 имя _DLLP1@0, тогда как TASM помещает имя без искажения. Это я учитываю в программе. Мы учитываем также возможность ошибки при вызове функций LoadLibrary и GetProcAddress. В этой связи укажем, как (в какой последовательности) ищет библиотеку функция LoadLibrary:
Файл библиотеки из предыдущего пункта.
Основной модуль:
dllex.asm:
.386P
; плоская модель
.MODEL FLAT, stdcall
; константы
; прототипы внешних процедур
IFDEF MASM
;MASM
EXTERN GetProcAddress@8:NEAR
EXTERN LoadLibraryA@4:NEAR
EXTERN FreeLibrary@4:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN MessageBoxA@16:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
EXTERN GetProcAddress:NEAR
EXTERN LoadLibraryA:NEAR
EXTERN FreeLibrary:NEAR
EXTERN ExitProcess:NEAR
EXTERN MessageBoxA:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\tasm32\lib\import32.lib
GetProcAddress@8 = GetProcAddress
LoadLibraryA@4 = LoadLibraryA
FreeLibrary@4 = FreeLibrary
ExitProcess@4 = ExitProcess
MessageBoxA@16 = MessageBoxA
ENDIF
;-----------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
TXT DB 'Ошибка динамической библиотеки',0
MS DB 'Сообщение',0
LIBR DB 'DLL1.DLL',0
HLIB DD ?
IFDEF MASM
NAMEPROC DB '_DLLP1@0',0
ELSE
NAMEPROC DB 'DLLP1',0
ENDIF
_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 _EXIT
YES_NAME:
PUSH 1 ; параметр
CALL EAX
; закрыть библиотеку
PUSH HLIB
CALL FreeLibrary@4
; библиотека автоматически закрывается также
; при выходе из программы
; выход
_EXIT:
PUSH 0
CALL ExitProcess@4
_TEXT ENDS
END START
1.bat:
c:\masm32\bin\ml /c /coff /DMASM dllex.asm
c:\masm32\bin\link /subsystem:windows dllex.obj
pause 0
Рис. 2 Результат работы программы
Неявное связывание
Мы здесь рассмотрим только вызывающую программу, так как вызываемая программа, естественно не меняется. Как видите, текст программы стал несколько проще. Здесь важно заметить, что, во-первых, необходимо объявить вызываемую из динамической библиотеки процедуру как внешнюю, а, во-вторых, подключить статическую библиотеку DLLP1.LIB.
Файл библиотеки тот же самый.
dllex.asm:
.386P
; плоская модель
IFDEF MASM
.MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF
; константы
; прототипы внешних процедур
includelib dll1.lib
IFDEF MASM
; MASM
EXTERN DLLP1@0:NEAR
EXTERN ExitProcess@4:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; директивы компоновщику для подключения библиотек
includelib c:\tasm32\lib\import32.lib
EXTERN DLLP1:NEAR
EXTERN ExitProcess:NEAR
DLLP1@0 = DLLP1
ExitProcess@4 = ExitProcess
ENDIF
;-----------------------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA ENDS
; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START:
PUSH 1 ; параметр
CALL DLLP1@0
; выход
_EXIT:
PUSH 0
CALL ExitProcess@4
_TEXT ENDS
END START
1.bat:
c:\masm32\bin\ml /c /coff /DMASM dllex.asm
c:\masm32\bin\link /subsystem:windows dllex.obj
pause 0
Рис. 3 Результат работы программы
Передача параметров
Основной процесс и динамическая библиотека используют одно и тоже адресное пространство.
Процесс передает адреса строк, которые находятся в блоке данных основного процесса.
В свою очередь, процедура возвращает в основной процесс адрес строки, находящейся в блоке данных динамической библиотеки:
dll2.asm:
; динамическая библиотека DLL2.ASM
.386P
; плоская модель
IFDEF MASM
.MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF
PUBLIC DLLP1
; константы
; сообщения, приходящие при открытии
; динамической библиотеки
DLL_PROCESS_DETACH equ 0
DLL_PROCESS_ATTACH equ 1
DLL_THREAD_ATTACH equ 2
DLL_THREAD_DETACH equ 3
IFDEF MASM
; MASM
; прототипы внешних процедур
EXTERN MessageBoxA@16:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
EXTERN MessageBoxA:NEAR
MessageBoxA@16 = MessageBoxA
includelib c:\tasm32\lib\import32.lib
ENDIF
;--------------------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
TEXT DB "Строка в динамической библиотеке",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
; закрытие библиотеки
JMP _EXIT
D1:
CMP EAX,1
JNE _EXIT
; открытие библиотеки
_EXIT:
MOV EAX,1
RET 12
;---------------------
; адреса параметров
; [EBP+8]
; [EBP+0CH]
DLLP1 PROC EXPORT
PUSH EBP
MOV EBP,ESP
PUSH 0
PUSH DWORD PTR [EBP+0CH]
PUSH DWORD PTR [EBP+8]
PUSH 0
CALL MessageBoxA@16
POP EBP
LEA EAX,TEXT
RET 8
DLLP1 ENDP
_TEXT ENDS
END DLLENTRY
dllex.asm:
; основной модуль DLLEX2.ASM, вызывающий
; процедуру из динамической библиотеки
.386P
; плоская модель
.MODEL FLAT, stdcall
; константы
; прототипы внешних процедур
IFDEF MASM
; MASM
EXTERN GetProcAddress@8:NEAR
EXTERN LoadLibraryA@4:NEAR
EXTERN FreeLibrary@4:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN MessageBoxA@16:NEAR
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
includelib c:\tasm32\lib\import32.lib
EXTERN GetProcAddress:NEAR
EXTERN LoadLibraryA:NEAR
EXTERN FreeLibrary:NEAR
EXTERN ExitProcess:NEAR
EXTERN MessageBoxA:NEAR
GetProcAddress@8 = GetProcAddress
LoadLibraryA@4 = LoadLibraryA
FreeLibrary@4 = FreeLibrary
ExitProcess@4 = ExitProcess
MessageBoxA@16 = MessageBoxA
ENDIF
;----------------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
TXT DB 'Ошибка динамической библиотеки',0
MS DB 'Сообщение',0
LIBR DB 'DLL2.DLL',0
HLIB DD ?
MS1 DB 'Сообщение из библиотеки',0
TEXT DB 'Это в основном модуле',0
IFDEF MASM
NAMEPROC DB '_DLLP1@0',0
ELSE
NAMEPROC DB 'DLLP1',0
ENDIF
_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 _EXIT
YES_NAME:
PUSH OFFSET MS1
PUSH OFFSET TEXT
CALL EAX
PUSH 0
PUSH OFFSET MS
PUSH EAX
PUSH 0
CALL MessageBoxA@16
; закрыть библиотеку
PUSH HLIB
CALL FreeLibrary@4
; библиотека автоматически закрывается также
; при выходе из программы
; выход
_EXIT:
PUSH 0
CALL ExitProcess@4
_TEXT ENDS
END START
1.bat:
c:\masm32\bin\ml /c /coff /DMASM dllex2.asm
c:\masm32\bin\link /subsystem:windows dllex2.obj
pause 0
Рис. 4 Результат работы программы (часть 1)
Рис. 5 Результат работы программы (часть 2)
Использование ресурсов
Основной процесс использует ресурсы загруженной им динамической библиотеки. Ресурсы можно поместить отдельно от основной программы в динамическую библиотеку, загружая их по мере необходимости.
Наша программа вначале загружает иконку из ресурсов динамической библиотеки и устанавливает ее на окно. Если щелкать левой кнопкой мыши, направив курсор на окно, то будет вызываться процедура из динамической библиотеки, которая будет поочередно устанавливать то один, то другой значок на окно.
dll3.rc:
// идентификаторы
#define IDI_ICON1 3
#define IDI_ICON2 10
// определили иконку
IDI_ICON1 ICON "ico1.ico"
IDI_ICON2 ICON "ico2.ico"
dllex.rc:
// определение констант
#define WS_SYSMENU 0x00080000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
#define DS_3DLOOK 0x0004L
// определение диалогового окна
DIAL1 DIALOG 0, 0, 340, 120
STYLE WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_3DLOOK
CAPTION "Диалоговое окно с иконкой из динамической библиотеки"
FONT 8, "Arial"
{
}
dll3.asm:
; динамическая библиотека DLL3.ASM
.386P
PUBLIC SETIC
; плоская модель
IFDEF MASM
.MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF
; константы
WM_SETICON equ 80h
IFDEF MASM
; MASM
; прототипы внешних процедур
EXTERN LoadIconA@8:NEAR
EXTERN PostMessageA@16:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
; прототипы внешних процедур
EXTERN LoadIconA:NEAR
EXTERN PostMessageA:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\tasm\lib\import32.lib
LoadIconA@8 = LoadIconA
PostMessageA@16 = PostMessageA
ENDIF
;-------------------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
PRIZ DB 0
_DATA ENDS
; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
DLLENTRY:
MOV EAX,1
RET 12
; [EBP+8]
; [EBP+0CH]
SETIC PROC EXPORT
PUSH EBP
MOV EBP,ESP
; выбрать, какую иконку устанавливать
CMP PRIZ,0
JZ IC_1
MOV PRIZ,0
PUSH 3
JMP CONT
IC_1:
MOV PRIZ,1
PUSH 10
CONT:
; загрузить иконку из ресурсов библиотеки
PUSH DWORD PTR [EBP+0CH] ; идентификатор
; динамической
; библиотеки
CALL LoadIconA@8
; установить значок окна
PUSH EAX
PUSH 0
PUSH WM_SETICON
PUSH DWORD PTR [EBP+08H] ; дескриптор окна
CALL PostMessageA@16
POP EBP
RET 8
SETIC ENDP
_TEXT ENDS
END DLLENTRY
dllex3.asm:
; основной модуль DLLEX3.ASM, вызывающий
; процедуру из динамической библиотеки
.386P
; плоская модель
IFDEF MASM
.MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF
; константы
; сообщение приходит при закрытии окна
WM_CLOSE equ 10h
WM_INITDIALOG equ 110h
WM_SETICON equ 80h
WM_LBUTTONDOWN equ 201h
; прототипы внешних процедур
IFDEF MASM
; MASM
EXTERN PostMessageA@16:NEAR
EXTERN GetProcAddress@8:NEAR
EXTERN LoadLibraryA@4:NEAR
EXTERN FreeLibrary@4:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN GetModuleHandleA@4:NEAR
EXTERN DialogBoxParamA@20:NEAR
EXTERN EndDialog@8:NEAR
EXTERN LoadIconA@8:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; директивы компоновщику для подключения библиотек
includelib c:\tasm\lib\import32.lib
EXTERN PostMessageA:NEAR
EXTERN GetProcAddress:NEAR
EXTERN LoadLibraryA:NEAR
EXTERN FreeLibrary:NEAR
EXTERN ExitProcess:NEAR
EXTERN GetModuleHandleA:NEAR
EXTERN DialogBoxParamA:NEAR
EXTERN EndDialog:NEAR
EXTERN LoadIconA:NEAR
PostMessageA@16 = PostMessageA
LoadIconA@8 = LoadIconA
EndDialog@8 = EndDialog
GetModuleHandleA@4 = GetModuleHandleA
DialogBoxParamA@20 = DialogBoxParamA
GetProcAddress@8 = GetProcAddress
LoadLibraryA@4 = LoadLibraryA
FreeLibrary@4 = FreeLibrary
ExitProcess@4 = ExitProcess
ENDIF
;------------------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
LIBR DB 'DLL3.DLL',0
HLIB DD ?
HINST DD ?
PA DB "DIAL1",0
IFDEF MASM
NAMEPROC DB "_SETIC@0",0
ELSE
NAMEPROC DB "SETIC",0
ENDIF
_DATA ENDS
; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START:
; получить дескриптор приложения
PUSH 0
CALL GetModuleHandleA@4
; создать диалог
MOV [HINST], EAX
PUSH 0
PUSH OFFSET WNDPROC
PUSH 0
PUSH OFFSET PA
PUSH [HINST]
CALL DialogBoxParamA@20
; выход
_EXIT:
PUSH 0
CALL ExitProcess@4
; процедура окна
; расположение параметров в стеке
; [EBP+014Н] ; LPARAM
; [EBP+10Н] ; WAPARAM
; [EBP+0CH] ; MES
; [EBP+8] ; HWND
WNDPROC PROC
PUSH EBP
MOV EBP,ESP
PUSH EBX
PUSH ESI
PUSH EDI
;-------------------
CMP DWORD PTR [EBP+0CH],WM_CLOSE
JNE L1
; закрыть библиотеку
; библиотека автоматически закрывается также
; при выходе из программы
PUSH HLIB
CALL FreeLibrary@4
PUSH 0
PUSH DWORD PTR [EBP+08H]
CALL EndDialog@8
JMP FINISH
L1:
CMP DWORD PTR [EBP+0CH],WM_INITDIALOG
JNE L2
; загрузить библиотеку
PUSH OFFSET LIBR
CALL LoadLibraryA@4
MOV HLIB,EAX
; загрузить иконку
PUSH 3 ; идентификатор иконки
PUSH [HLIB] ; идентификатор процесса
CALL LoadIconA@8
; установить иконку
PUSH EAX
PUSH 0 ; тип иконки (маленькая)
PUSH WM_SETICON
PUSH DWORD PTR [EBP+08H]
CALL PostMessageA@16
JMP FINISH
L2:
CMP DWORD PTR [EBP+0CH],WM_LBUTTONDOWN
JNE FINISH
; получить адрес процедуры из динамической библиотеки
PUSH OFFSET NAMEPROC
PUSH HLIB
CALL GetProcAddress@8
; вызвать процедуру с двумя параметрами
PUSH [HLIB]
PUSH DWORD PTR [EBP+08H]
CALL EAX
FINISH:
POP EDI
POP ESI
POP EBX
POP EBP
MOV EAX,0
RET 16
WNDPROC ENDP
_TEXT ENDS
END START
1.bat:
c:\masm32\bin\ml /c /coff /DMASM dllex3.asm
c:\masm32\bin\rc dllex3.rc
c:\masm32\bin\link /subsystem:windows dllex3.obj dllex3.res
pause 0
c:\masm32\bin\ml /c /coff /DMASM dll3.asm
c:\masm32\bin\rc dll3.rc
c:\masm32\bin\link /subsystem:windows /DLL /ENTRY:DLLENTRY dll3.obj dll3.res
pause 0
Рис. 6 Результат работы программы (часть 1)
Рис. 7 Результат работы программы (часть 2)
Использование общей памяти
Запускаемое приложение загружает динамическую библиотеку и вызывает процедуру из динамической библиотеки, которая меняет данные, расположенные опять же в динамической библиотеке. Запустим теперь второй экземпляр приложения. Оно загружает еще один экземпляр динамической библиотеки. Могут быть ситуации, когда желательно, чтобы второе запущенное приложение "знало", что по команде первого приложения данные уже изменились. Ясно, что в этом случае данные, которыми оперирует динамическая библиотека, должны быть общими. Технически это делается очень просто.
У редактора связей LINK есть опция /section: имя, атрибуты, которая позволяет объявить явно свойства данной секции. Достаточно сказать, что секция - это просто сегмент в старом понимании. В редакторе связей TLINK32 то же действие можно осуществить с помощью файла .DEF.
Перед выходом из процедуры динамической библиотеки изменяется строка, хранящаяся в разделяемой секции памяти. При этом приложение не заканчивает своей работы. При запуске второго экземпляра приложения на экран выводится уже измененное первым приложением значение строки.
dll4.asm:
; динамическая библиотека DLL4.ASM
.386P
; плоская модель
IFDEF MASM
.MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF
PUBLIC DLLP1
IFDEF MASM
; MASM
; прототипы внешних процедур
EXTERN MessageBoxA@16:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
EXTERN MessageBoxA:NEAR
MessageBoxA@16 = MessageBoxA
includelib c:\tasm\lib\import32.lib
ENDIF
;--------------------------------------------------
; сегмент данных
_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
RET
DLLP1 ENDP
_TEXT ENDS
END DLLENTRY
dllex4.asm:
; основной модуль DLLEX4.ASM, вызывающий
; процедуру из динамической библиотеки
.386P
; плоская модель
.MODEL FLAT, stdcall
; константы
; прототипы внешних процедур
IFDEF MASM
; MASM
EXTERN GetProcAddress@8:NEAR
EXTERN LoadLibraryA@4:NEAR
EXTERN FreeLibrary@4:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN MessageBoxA@16:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ELSE
; директивы копоновщику для подключения библиотек
includelib c:\tasm\lib\import32.lib
EXTERN GetProcAddress:NEAR
EXTERN LoadLibraryA:NEAR
EXTERN FreeLibrary:NEAR
EXTERN ExitProcess:NEAR
EXTERN MessageBoxA:NEAR
GetProcAddress@8 = GetProcAddress
LoadLibraryA@4 = LoadLibraryA
FreeLibrary@4 = FreeLibrary
ExitProcess@4 = ExitProcess
MessageBoxA@16 = MessageBoxA
ENDIF
;----------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
TXT DB 'Ошибка динамической библиотеки',0
MS DB 'Сообщение',0
LIBR DB 'DLL4.DLL',0
HLIB DD ?
IFDEF MASM
NAMEPROC DB '_DLLP1@0',0
ELSE
NAMEPROC DB 'DLLP1',0
ENDIF
_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 _EXIT
YES_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 ENDS
END START
1.bat:
c:\tasm\bin\tasm32 /ml dll4.asm
c:\tasm\bin\tlink32 -aa -Tpd dll4.obj,,,,dll4.def
c:\tasm\bin\tasm32 /ml dllex4.asm
c:\tasm\bin\tlink32 -aa dllex4.obj
pause 0
Рис. 8 Результат работы программы (часть 1)
Рис. 9 Результат работы программы (часть 2)
Вывод
Для компиляции использовались компиляторы MASM32 и TASM32.
Таким образом можно сделать вывод, что использование динамических библиотек очень удобно при модульном построении программы.
Список литературы
1) Динамически подключаемая библиотека. URL: http://ru.wikipedia.org/wiki/Динамически_подключаемая_библиотека/
(Дата обращения 20.04.2014).
2) Пирогов Владислав Юрьевич. Ассемблер для Windows. -- М.: Издатель Молгачева С.В., 2002. --552 с., ил. - ISBN 5-94740-003-0.
3) Динамические библиотеки. Общие положения. URL: http://www.cracklab.ru/pro/cpp.php?r=appli&d=zart178/
(Дата обращения 20.04.2014)
Размещено на Allbest.ru=
...Подобные документы
Основные функции библиотеки динамической компоновки (DLL) в операционной системе Windows. Характеристика механизмов связывания в среде Windows. Описание функций, использующихся в программах. Анализ примеров реализации DLL. Процесс использования ресурсов.
курсовая работа [365,3 K], добавлен 18.05.2014Рассмотрение понятия, назначения и преимуществ использования динамических библиотек; способы их связи с приложениями. Принципы работы с системным реестром Windows NT. Характеристика процессов и потоков как основополагающих компонент операционной системы.
лабораторная работа [760,6 K], добавлен 08.09.2011Основные типы динамических подключаемых библиотек DLL: исполняемые и библиотеки ресурсов. Способы экспорта процедур и функций: по имени и порядковому номеру. Системные требования к разработке программы для организации проведения опросов (тестов).
курсовая работа [124,3 K], добавлен 23.07.2012Теоретические основы разработки Windows-приложений с использованием библиотеки MFC. Создание приложения с помощью Visual C++. Описание логической структуры приложения. Установка и запуск программы. Входные и выходные данные. Преимущество MFC библиотек.
курсовая работа [563,2 K], добавлен 21.06.2011Стандартная библиотека для всех 32-разрядных операционных систем - OpenGL. Структурная схема программы. Описание разработанного класса, реализации технологии Com, динамических библиотек. Средства использования сервисов, предоставляемых Microsoft Office.
курсовая работа [4,3 M], добавлен 14.11.2010Понятие и виды электронных ресурсов муниципальных библиотек. Организация и использование электронных ресурсов в муниципальных библиотеках РФ. Анализ современного состояния и основные тенденции развития электронных ресурсов муниципальных библиотек.
курсовая работа [77,9 K], добавлен 16.05.2017Проектирование и отладка Windows-приложений для работы с внешними источниками данных. Функциональная блок-схема взаимодействия программных модулей. Описание связей между таблицами. Тестирование программного средства. Требования к техническому обеспечению.
курсовая работа [2,7 M], добавлен 17.05.2011Необходимость существования, критерии анализа и выбора электронных библиотек. Виды электронных библиотек - универсальные, электронные библиотеки периодических изданий и книг. Особенности распространения информационно-коммуникационных технологий.
курсовая работа [5,6 M], добавлен 04.05.2013Анализ временных рядов. Разработка программы для среды визуального проектирования Borland Delphi 7.0. Математическая формулировка задачи. Структурная схема программы. Описание реализации технологии COM, динамических библиотек, возможностей программы.
курсовая работа [4,3 M], добавлен 14.11.2010Компиляция программ на языке C/C++. Компиляция нескольких файлов. Библиотеки объектных файлов. Создание статической и динамической библиотеки. Функции работы. Создание динамической библиотеки для решения системы линейных уравнений.
курсовая работа [27,4 K], добавлен 07.08.2007Использование Windows Installer с целью управления установкой и конфигурированием приложений. Работа в среде Microsoft Word: создание текстового документа со встроенным готовым рисунком. Разработка алгоритма и программы расчета ежемесячной квартплаты.
контрольная работа [1,3 M], добавлен 31.05.2012Разработка предложений по внедрению биометрической аутентификации пользователей линейной вычислительной сети. Сущность и характеристика статических и динамических методов аутентификации пользователей. Методы устранения угроз, параметры службы защиты.
курсовая работа [347,3 K], добавлен 25.04.2014Использование стандартных библиотек Windows. Установка и настройка дополнительных устройств ввода/вывода. Использование камеры, динамиков, сканера, дисков и портов ввода/вывода. Драйверы внешних устройств. Безопасность данных в операционных системах.
контрольная работа [1,8 M], добавлен 13.10.2022Теоретические основы написания Windows-приложений с использованием библиотеки MFC. Основы программирования под Windows. Проектирование приложений в среде Microsoft Visual C++. Описание логической структуры приложения, его функциональное назначение.
курсовая работа [1,3 M], добавлен 12.12.2011Изучение теоретических положений, раскрывающие структуру линейных и нелинейных стационарных и динамических объектов, математическое описание и решение задачи анализа объектов. Использование для решения функции системы математических расчетов MathCAD.
контрольная работа [317,7 K], добавлен 16.01.2009Интерфейс API, реализация функций API на уровне ОС, системы программирования и с помощью внешних библиотек. Характеристики сетевого интерфейса прикладного программирования Winsock, особенности его применения в операционных системах UNIX и Windows.
контрольная работа [74,2 K], добавлен 04.06.2015Архитектура операционной системы Android, набор библиотек для обеспечения базового функционала приложений и виртуальная машина Dalvik. Объектно-ориентированный язык программирования Java как инструмент разработки мобильных приложений для ОС Android.
дипломная работа [1,6 M], добавлен 08.07.2015Проект экспериментального программного комплекса индексирования и поиска неструктурированной текстовой информации в многоязычной среде, состоящего из математических моделей, алгоритмов и программных средств. Исследование характеристик его эффективности.
автореферат [296,5 K], добавлен 31.01.2012Интегрированная среда разработки Delphi и элементы, входящие в ее состав. Математическая модель, алгоритм решения и его свойства. Описание операторов, процедур, функций и методов. Создание приложений по аналитической геометрии и теоретической механике.
курсовая работа [1,8 M], добавлен 26.05.2010Основы программирования на 32-битном Ассемблере, разработка с его помощью программы, демонстрирующей работу одного из разделов ОС Windоws. Описание используемых АРI-функций как интерфейса программирования приложений. Листинг программы, результаты работы.
курсовая работа [164,5 K], добавлен 18.05.2014