
Передача параметров
Основной процесс и динамическая библиотека используют одно и тоже адресное пространство. Процесс передает адреса строк, которые находятся в блоке данных основного процесса. В свою очередь, процедура возвращает в основной процесс адрес строки, находящейся в блоке данных динамической библиотеки:
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)