Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчеты по Курсовой Работе / Создание динамических библиотек 8-78-1 Брагин Г. В.doc
Скачиваний:
33
Добавлен:
12.03.2015
Размер:
231.42 Кб
Скачать

Явное связывание

Библиотека должна быть вначале загружена при помощи функции LoadLibrary. Затем определяется адрес процедуры с помощью функции GetProcAddress, после чего можно осуществлять вызов. Как и следовало ожидать, MASM помещает в динамическую библиотеку вместо DLLP1 имя _DLLP1@0, тогда как TASM помещает имя без искажения. Это я учитываю в программе. Мы учитываем также возможность ошибки при вызове функций LoadLibrary и GetProcAddress. В этой связи укажем, как (в какой последовательности) ищет библиотеку функция LoadLibrary:

Файл библиотеки из предыдущего пункта.

Основной модуль:

dllex.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

EXTERN GetProcAddress:NEAR

EXTERN LoadLibraryA:NEAR

EXTERN FreeLibrary:NEAR

EXTERN ExitProcess:NEAR

EXTERN MessageBoxA:NEAR

; директивы компоновщику для подключения библиотек

includelib c:\tasm32\lib\import32.lib

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 'DLL1.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'

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 1 ; параметр

CALL EAX

; закрыть библиотеку

PUSH HLIB

CALL FreeLibrary@4

; библиотека автоматически закрывается также

; при выходе из программы

; выход

_EXIT:

PUSH 0

CALL ExitProcess@4

_TEXT ENDS

END START

1.bat:

c:\masm32\bin\ml /c /coff /DMASM dllex.asm

c:\masm32\bin\link /subsystem:windows dllex.obj

pause 0

Рис. 2. Результат работы программы

Неявное связывание

Мы здесь рассмотрим только вызывающую программу, так как вызываемая программа, естественно не меняется. Как видите, текст программы стал несколько проще. Здесь важно заметить, что, во-первых, необходимо объявить вызываемую из динамической библиотеки процедуру как внешнюю, а, во-вторых, подключить статическую библиотеку DLLP1.LIB.

Файл библиотеки тот же самый.

dllex.asm:

.386P

; плоская модель

IFDEF MASM

.MODEL FLAT, stdcall

ELSE

.MODEL FLAT

ENDIF

; константы

; прототипы внешних процедур

includelib dll1.lib

IFDEF MASM

; MASM

EXTERN DLLP1@0:NEAR

EXTERN ExitProcess@4:NEAR

; директивы компоновщику для подключения библиотек

includelib c:\masm32\lib\user32.lib

includelib c:\masm32\lib\kernel32.lib

ELSE

; директивы компоновщику для подключения библиотек

includelib c:\tasm32\lib\import32.lib

EXTERN DLLP1:NEAR

EXTERN ExitProcess:NEAR

DLLP1@0 = DLLP1

ExitProcess@4 = ExitProcess

ENDIF

;-----------------------------------------------------

; сегмент данных

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

_DATA ENDS

; сегмент кода

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

START:

PUSH 1 ; параметр

CALL DLLP1@0

; выход

_EXIT:

PUSH 0

CALL ExitProcess@4

_TEXT ENDS

END START

1.bat:

c:\masm32\bin\ml /c /coff /DMASM dllex.asm

c:\masm32\bin\link /subsystem:windows dllex.obj

pause 0

Рис. 3. Результат работы программы