Rambler's
Top100

Статическое и динамическое подключение библиотек .DLL в Windows

Автор: lonesome TSH/Digital Daemons
Дата: .01.2003
Раздел: Низкоуровневое программирование в Windows

Обычный способ загрузки функций из DLL - статическое подключение. При старте вашей программы подключенная таким образом функция уже загружена и находится в адресном пространстве программы. С точки зрения ассемблера статическая загрузка функций происходит таким образом:

extern ИмяФункции;объявление внешней функции
...код программы
call ИмяФункции;вызов функции
...код программы

Загрузку этих функций выполняет загрузчик исполняемых файлов и производится это при старте программы. Очевидно что такой способ является самым простым, но неоптимальным:

1) Если необходимых программе функций и библиотек много, то процесс их загрузки может занять значительное время

2) Функции будут отнимать оперативную память, причем все и одновременно, хотя программе возможно они не нужны в один и тот же момент времени

3) Если какая-нибудь из необходимых библиотек отсутствует, то загрузка программы станет невозможна, т.е. таким образом невозможно реализовать, например, механизм плагинов

4) В конце концов, компоновщику при компоновке программы понадобятся .LIB файлы на каждую подключаемую библиотеку, и хотя их легко сделать из существующих DLL, но иногда просто лень :)

Недостатков статической лишена динамическая компоновка, которая происходит только тогда, когда она нужна. Выгрузить библиотеку из памяти также можно в любой момент времени.
Загрузка библиотеки происходит по вызову функции LoadLibrary, которая принимает в качестве параметра имя библиотеки. После загрузки библиотеки, адреса каждой нужной функции можно получить с помощью функции GetProcAddress, которой нужно сообщить выданный первой функцией обработчик и имя функции

В нижепреведенном примере я использовал динамическую компоновку для подключения функции printf из библиотеки CRTDLL.DLL - стандартной библиотеки Си.

extern LoadLibraryA 
extern GetProcAddress 
extern ExitProcess 
 
[segment code public use32 class='CODE'] 
 
 
..start: 
push dword lib 
call LoadLibraryA 
mov [handle], eax 
 
;Импортирование функции printf:
push dword func_printf 
push eax 
call GetProcAddress 
mov [printf], eax ;адрес printf был в eax
 
;Импортирование функции _getch:
push dword func_getch 
push dword [handle] 
call GetProcAddress 
mov [getch], eax 
 
 
;Вызов функции printf: 
push dword message 
call [printf] 
 
;Вызов функции getch 
call [getch] 
 
 
push dword 0 
call ExitProcess 
 
lib db "crtdll.dll",0 
func_printf db "printf",0 
func_getch db "_getch",0 

message db "An example of dynamic importing of C 
runtime library functions",0x0A,0x0D, "Press Any Key",
0x0A, 0x0D, 0 
 
printf dd 0 
getch dd 0 
handle dd 0 

Компиляция:
nasm -fobj dynamicdll.asm

Компоновка:
alink -oPE -subsys console dynamicdll.obj win32.lib



Rambler's Top100