Главная » Win32 API » Примеры приложений, работающих с собственными DLL

0

Рассмотрим использование собственных DLL на нескольких при­мерах.

Пример 1. Рассмотрим три функции, включаемых в DLL: вычисле­ние степени числа, преобразование числа в строку и вывод числа, хра­нящегося в регистре еах.

Сначала напишем код, в котором реализуются функции DLL. Назо­вем файл MyDLL.asm.

.model flat, stdcall option casemap :none

include d:\masm32\include\windows.inc include d:\masm32\include\user32.inc include d:\masm32\include\kernel32.inc includelib d:\masm32\lib\user32.lib includelib d:\masm32\lib\kernel32.lib szText MACRO Name, Text:VARARG LOCAL 1Ы

jmp 1Ы

Name db Text,0

1Ы: ENDM

m2m MACRO Ml, M2 push M2 pop Ml ENDM

return MACRO arg mov eax, arg ret ENDM .data

hlnst dd 0 buf db 5 dup(O)

szDisplayName db "Сообщение",0 . code LibMain proc hInstDLL:DWORD, reason:DWORD,

unused:DWORD szText LmTitle,"tstdll’s LibMain Function" mov eax,hInstDLL mov hlnst,eax

.if reason == DLL_PROCESS_ATTACH

szText ATTACHPROCESS,"PROCESS_ATTACH" invoke MessageBox,NULL,ADDR ATTACHPROCESS,

addr LmTitle,MB_OK return TRUE .elseif reason == DLL_PROCESS_DETACH

szText DETACHPROCESS,"PROCESS_DETACH" invoke MessageBox,NULL,addr DETACHPROCESS, addr LmTitle,MB_OK .elseif reason == DLL_THREAD_ATTACH

szText ATTACHTHREAD,"THREAD_ATTACH" invoke MessageBox,NULL,addr ATTACHTHREAD, addr LmTitle,MB_OK .elseif reason == DLL_THREAD_DETACH

szText DETACHTHREAD,"THREAD_DETACH" invoke MessageBox,NULL,addr DETACHTHREAD, addr LmTitle,MB_OK .endif ret

LibMain Endp ; Функции библиотеки ; степень аЛЬ

step proc a :DWORD, b :DWORD mov eax,0 mov ecx,b mov eax,1 11: mul a loop 11 return eax

step endp

; Перевод из числа в строку

IntToStr proc a :DWORD

mov eax,a

mov ebx,10

mov ecx,0

conv: .if eax & 8000h

mov edx,Offffh .else

mov edx,Oh .endif

div ebx

or dl,30h

ror ecx,8

mov cl,dl

cmp eax,0

jne conv

ror ecx,8

return ecx IntToStr endp

; вывод содержимого регистра еах out_eax proc

mov buf[4],0

mov buf[3],al

shr eax,8

mov buf[2],al

shr eax,8

mov buf[1],al

shr eax,8

mov buf[0],al

invoke MessageBox,NULL,ADDR buf, ADDR szDisplayName,MB_OK

return 0 out_eax endp End LibMain

Экспортируемые функции из библиотеки описываются в файле MyDll.def:

LIBRARY MyDll EXPORTS step EXPORTS IntToStr EXPORTS out eax

Для демонстрации вызова функций из библиотеки напишем при­ложение, на форме которого расположим два элемента Edifflox для ввода чисел и кнопку для выполнения вычислений и вывода результа­та с помощью функций из библиотеки. Текст приложения, хранимый в файле MyCallDll.asm, приведен ниже.

.model flat, stdcall

option casemap :none

include d:\masm32\include\windows.inc

include d:\masm32\include\user32.inc

include d:\masm32\include\kernel32.inc

includelib d:\masm32\lib\user32.lib

includelib d:\masm32\lib\kernel32.lib

szText MACRO Name, Text:VARARG

LOCAL 1Ы jmp 1Ы

Name db Text,0 1Ы: ENDM m2m MACRO Ml, M2

push M2

pop Ml ENDM return MACRO arg

mov eax, arg

ret ENDM

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD TopXY PROTO   :DWORD,:DWORD ; функция для создания кнопки Pushbutton PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,

:DWORD,:DWORD ; функция для создания EditBox EditSl PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,

:DWORD,:DWORD EdlProc PROTO :DWORD,:DWORD,:DWORD,:DWORD .data

szDisplayName db "Работа с DLL: посчитать аЛЬ",0 CommandLine dd 0 hWnd dd 0 ; дескриптор окна hlnstance dd 0 ; дескриптор приложения aa dd 0

step  dd 0

IntToStr  dd 0

out_eax dd 0

hEditl  dd 0

; дескриптор первого EditBox

hEdit2  dd 0

; дескриптор второго EditBox

nuUbyte db 0

lpfnEdlProc dd 0

; адрес оконной функции EditBox

numl  dd 0 ; первое число

mim2  dd 0 ; второе число

. code

start:

invoke GetModuleHandle, NULL

mov hlnstance, eax

invoke GetCommandLine

mov CommandLine, eax

invoke WinMain,hlnstance,NULL,CommandLine, SW_SHOWDEFAULT

invoke ExitProcess,eax WinMain proc hlnst     :DWORD, hPrevInst :DWORD, CmdLine   :DWORD, CmdShow   :DWORD

LOCAL wc   :WNDCLASSEX

LOCAL msg  :MSG

LOCAL Wwd  :DWORD

LOCAL Wht  :DWORD

LOCAL Wtx  : DWORD

LOCAL Wty  :DWORD

mov wc.cbSize, sizeof WNDCLASSEX

mov wc.style, CS_HREDRAW or CS_VREDRAW \ or CS_BYTEALIGNWINDOW

mov wc.lpfnWndProc,  offset WndProc

mov wc.cbClsExtra, NULL

mov wc.cbWndExtra, NULL

m2m wc.hlnstance, hlnst

mov wc.hbrBackground,  COLOR_BTNFACE+l

mov wc.lpszMenuName, NULL

mov wc.lpszClassName,  offset szClassName

invoke LoadIcon,hlnst,500 ; идентификатор ;  пиктограммы из файла ресурсов

mov wc.hlcon, eax

invoke LoadCursor,NULL,IDC_ARROW

mov wc.hCursor, eax

mov wc.hlconSm, 0

invoke RegisterClassEx, ADDR wc ; для вывода окна в центре экрана получим его размеры mov Wwd, 290 mov Wht, 200

invoke GetSystemMetrics,SM_CXSCREEN invoke TopXY,Wwd,eax mov Wtx, eax

invoke GetSystemMetrics,SM_CYSCREEN invoke TopXY,Wht,eax mov Wty, eax

szText szClassName,"CallDLL_Class" invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,

ADDR szClassName, ADDR szDisplayName, WS_OVERLAPPEDWINDOW, Wtx,Wty,Wwd, Wht, NULL,NULL, hInst,NULL mov hWnd,eax

invoke ShowWindow,hWnd,SW_SHOWNORMAL invoke UpdateWindow,hWnd StartLoop:

invoke GetMessage,ADDR msg,NULL,0,0 amp eax, 0 je ExitLoop

invoke TranslateMessage, ADDR msg invoke DispatchMessage,  ADDR msg jmp StartLoop ExitLoop:

return msg.wParam WinMain endp ; оконная функция WndProc proc hWin:DWORD, uMsg   :DWORD,

wParam :DWORD, lParam :DWORD LOCAL hLib  :DWORD .if uMsg == WM_COMMAND ;если нажата кнопка

.if wParam == 500 jmp @F

libName db "MyDll.dll",0 FuncName db "step",0 FuncName2 db "IntToStr",0 sout_eax db "out_eax",0 @@:

invoke LoadTii brary,ADDR libName mov hLib, eax invoke GetProcAddress,hLib,ADDR FuncName2

mov IntToStr,eax

invoke GetProcAddress,hLib,ADDR sout_eax mov out_eax,eax

invoke GetProcAddress,hLib,ADDR FuncName mov step,eax push dword ptr numl push dword ptr num2 call step push eax call IntToStr call out_eax invoke FreeLibrary,hLib .endif .elseif uMsg == WM_CREATE

szText Butnl,"Посчитать"

invoke PushButton,ADDR Butnl,hWin,

20,20,140,25,500 invoke EditSl,ADDR nulbyte,120,60,

100,23,hWin,200 mov hEditl, eax invoke EditSl,ADDR nulbyte,20,100,

100,23,hWin,200 mov hEdit2, eax invoke SetWindowLong,hEditl,GWL_WNDPROC,

EdlProc mov lpfnEdlProc, eax invoke SetWindowLong,hEdit2,GWL_WNDPROC,

EdlProc mov lpfnEdlProc, eax .elseif uMsg == WM_DESTROY

invoke PostQuitMessage,NULL return 0 .endif

invoke DefWindowProc,hWin,uMsg,wParam,IParam ret WndProc endp

; получение координат центра экрана TopXY proc wDim:DWORD, sDim:DWORD shr sDim, 1 shr wDim, 1 mov eax, wDim sub sDim, eax return sDim TopXY endp ; создание кнопки PushButton proc IpText:DWORD,hParent:DWORD,

a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD

szText btnClass,"BUTTON"

invoke CreateWindowEx,0, ADDR btnClass,lpText, WS_CHILD or WS_VISIBIiE, a,b,wd,ht,hParent,ID,hlnstance,NULL ret Pushbutton endp ; создание EditBox EditSl proc szMsg:DWORD,a:DWORD,b:DWORD,

wd:DWORD,ht:DWORD,hParent:DWORD,ID:DWORD szText slEdit,"EDIT"

invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR slEdit,szMsg,

WS_VISIBLE or WS_CHILDWINDOW or \ ES_AUTOHSCROLL or ES_NOHIDESEL, a,b,wd,ht,hParent,ID,hlnstance,NULL ret EditSl endp

; оконная функция для EditBox EdlProc proc hCtl   :DWORD, uMsg   :DWORD,

wParam :DWORD, lParam :DWORD ; формирование числа из строки .if uMsg == WM_CHAR

.if wParam == 8                                ; нажат backspace

mov eax,hEditl .if hCtl = eax

mov numl,0 .else

mov num2,0 .endif

jmp accept .endif .if wParam < "0"

return 0 .endif .if wParam > "9"

return 0 .endif

mov eax,hEditl .if hCtl = eax

.if numl == 0

mov ebx,wParam and ebx,Ofh mov numl,ebx .else

mov eax,numl mov bx,10

mul Ьх

mov ebx,wParam and bx,Ofh add ax,bx mov numl, eax .endif .elseif

.if num2 = 0

mov ebx,wParam and ebx,Ofh mov num2 , ebx .else

mov eax,num2 mov bx,10 mul bx

mov ebx,wParam and bx,Ofh add ax,bx mov num2,eax .endif .endif .endif accept:

invoke CallWindowProc,lpfnEdlProc,hCtl,uMsg, wParam,lParam ret EdlProc endp end start

Создание библиотеки MyDll.dll осуществляется при запуске bat-файла вида:

@echo  off

if exist MyDll.obj del MyDll.obj

if exist MyDll.dll del MyDll.dll

d:\masm32\bin\ml /c /coff MyDll.asm

d:\masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL

/DEF:MyDll.def MyDll.obj

pause

Создание исполняемого файла осуществляется при запуске bat-файла: @echo  off

if exist MyCallDll.obj del MyCallDll.obj if exist MyCallDll.exe del MyCallDll.exe if exist rsrc.res del rsrc.res

if exist rsrc.obj del rsrc.obj

d:\masm3 2\BIN\Rc.exe /v rs re.гс

d:\masm32\BIN\Cvtres.exe /machine:ix86 rsrc.res

d:\masm32\bin\ml /c /coff MyCallDll.asm

d:\masm32\bin\link.exe /SUBSYSTEM:WINDOWS MyCallDll.obj

rsrc.obj

pause

Пример работы приложения приведен на рисунке 3.5.

Рисунок 3.5

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

По теме:

  • Комментарии