Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Функция GetProcAddress применяется для получения адреса функции, находящейся в DLL. Впоследствии приложение может использовать этот адрес для вызова функции. GetProcAddress имеет систаксис:
FARPROC GetProcAddress(HMODULE hModule, // дескриптор DLL, возвращенный // функцией LoadLibrary

При успешном завершении функция возвращает адрес точки входа запрашиваемой процедуры. Наконец, функция FreeLibrary вызывается в том случае, если нужно сообщить Windows, что указанная библиотека DLL приложением более не используется. Windows декрементирует счетчик использований DLL, и когда он становится равным нулю, DLL удаляется из памяти.
Функция имеет синтаксис:
BOOL FreeLibrary(HMODULE hModule);
где hModule — дексриптор модуля DLL.
LPCSTR lpProcName // имя функции

Последующий пример демонстрирует использование динамической загрузки DLL для вызова процедур Sum2 и Sub2. Исходный текст программы приведен в листинге 5.27.

Листинг 5.27. Программа, демонстрирующая вызов функций из динамически загружаемой DLL
. CALLSUM2 . ASM
.386
.model flat, stdcaii
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

Прототипы функций
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
.data
szClassName DB "LoadDLL_Class", 0
szDisplayName DB "ДИНАМИЧЕСКАЯ ЗАГРУЗКА
slnts DB "ПЕРВОЕ ЧИСЛО = 2 3 , ВТОРОЕ ЧИСЛО = -54"
lslnts EQU $-sInts
isum DD 0
isub DD 0
lpFmt DB "%s%d", 0
si DB "СУММА = ", 0
s2 DB "РАЗНОСТЬ = ", 0
buf DB 32 dup (0)
stitlel DB "ВЫЧИСЛЕНИЕ СУММЫ ДВУХ ЦЕЛЫХ ЧИСЕЛ", 0
stitle2 DB "ВЫЧИСЛЕНИЕ РАЗНОСТИ ДВУХ ЦЕЛЫХ ЧИСЕЛ", 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
Заполнение структуры WNDCLASSEX требуемыми параметрами
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or ,CS_VREDRAW or СS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbCIsExtra, NULL
mov wc.cbWndExtra, NULL
push hlnst
pop wc.hlnstance
mov wc.hbrBackground, COLOR_WINDOW-l
mov wc.hbrBackground, COLOR_WINDOW-l
mov wc.IpszMenuName, NULL
mov wc.IpszClassName, offset szClassName
invoke Loadlcon, hlnst, 500
mov wc.hlcon, EAX
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, EAX
mov wc.hlconSm, 0
invoke RegisterClassEx, ADDR wc
invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, ADDR szClassName,\
ADDR szDisplayName, WS_OVERLAPPEDWINDOW,\
CWJJSEDEFAULT, CWJJSEDEFAULT, CWJJSEDEFAULT, \
CWJJSEDEFAULT, NULL, NULL, hlnst, NULL
mov hWnd, EAX
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke Updatewindow, hWnd
StartLoop:
invoke GetMessage, ADDR msg, NULL, 0, 0
cmp EAX, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
mov EAX, msg.wParam
WinMain endp

Оконная процедура
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL hLib :DWORD
LOCAL hdc :HDC
LOCAL rect :RECT
LOCAL ps :PAINTSTRUCT
cmp uMsg, WM_PAINT
jne next_l
lea EDX, ps
push EDX
push hWin
call BeginPaint
mov hdc, EAX
invoke TextOut, hdc, 10, 10, ADDR slnts, lslnts
lea EDX, ps
push EDX
push hWin
call EndPaint
ret
next_l:
cmp uMsg, WM__LBUTTONDOWN
ne next_2
invoke LoadLibrary, ADDR libName
mov hLib, EAX
invoke GetProcAddress, hLib, ADDR FuncSumName
push i2
push il
call EAX
mov isum, EAX
invoke FreeLibrary, hLib
push isum
push offset si
push offset lpFmt
push offset buf
call wsprintf
add ESP, 16
invoke MessageBox, hWin, ADDR buf, ADDR stitlel, MB_OK
ret
next_2:
cmp uMsg, WM_RBUTTONDOWN
ne next_3
invoke LoadLibrary, ADDR libName
mov hLib, EAX
invoke GetProcAddress, hLib, ADDR FuncSubName
push i2
push il
call EAX
mov isub, EAX
invoke FreeLibrary, hLib
push isub
push offset s2
push offset lpFmt
push offset buf
call wsprintf
add ESP, 16
invoke MessageBox, hWin, ADDR buf, ADDR stitle2, MB_OK
ret
WndProc endp
end start

Остановлюсь на наиболее интересных фрагментах кода приложения
CALLSUM2. Загрузка библиотеки Sum2.dll в память выполняется в следующих
строках:
invoke LoadLibrary, ADDR libName
mov hLib, EAX

Возвращаемый функцией LoadLibrary дескриптор модуля запоминается в
переменной hLib, которая используется при вызове процедур Sum2 и Sub2:
invoke GetProcAddress, hLib, ADDR FuncSumName
push i2
push il
call EAX
mov isum, EAX
invoke GetProcAddress, hLib, ADDR FuncSubName
push i2
push il
call EAX
mov isub, EAX

В обоих фрагментах кода функция GetProcAddress возвращает адреса процедур
Sum2 и Sub2 в регистре ЕАХ. Поэтому можно использовать команду:
call ЕАХ
для вызова процедур по адресу в ЕАХ.

Наконец, рассмотрим консольные приложения Windows.


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru