
Использование общей памяти
Запускаемое приложение загружает динамическую библиотеку и вызывает процедуру из динамической библиотеки, которая меняет данные, расположенные опять же в динамической библиотеке. Запустим теперь второй экземпляр приложения. Оно загружает еще один экземпляр динамической библиотеки. Могут быть ситуации, когда желательно, чтобы второе запущенное приложение "знало", что по команде первого приложения данные уже изменились. Ясно, что в этом случае данные, которыми оперирует динамическая библиотека, должны быть общими. Технически это делается очень просто.
У редактора связей 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)
Рис. 69. Результат работы программы (часть 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)