На этом шаге мы приведем пример неявного связывания.
Хотя мы отмечали, что, по нашему мнению, неявное связывание менее гибко, мы приведем пример неявного связывания. Мы здесь рассмотрим только вызывающую программу, так как вызываемая программа, естественно, не меняется. Как видите, текст программы стал несколько проще. Здесь важно заметить, что, во-первых, необходимо объявить вызываемую из DLL процедуру как внешнюю, а, во-вторых, подключить статическую библиотеку DLLP1.LIB.
.386P ;Плоская модель. IFDEF MASM .MODEL FLAT, STDCALL ELSE .MODEL FLAT ENDIF ;Константы. ;Прототипы внешних процедур. includelib pr71_1.lib IFDEF MASM ;MASM EXTERN DLLP1@0:NEAR EXTERN ExitProcess@4:NEAR ;Директивы компоновщику для подключения библиотек. ;Для компоновщика LINK.EXE. includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ELSE ;TASM EXTERN DLLP1:NEAR EXTERN ExitProcess:NEAR DLLP1@0 = DLLP1 ExitProcess@4 = ExitProcess ;Для компоновщика TLINK32.EXE. includelib c:\tasm32\lib\import32.lib 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
У читателя, скорее всего, возникнет вопрос, откуда появляется библиотека DLLP1.LIB. Транслятор MASM создает ее автоматически, а в TASM есть утилита IMPLIB, которая создает статическую библиотеку непосредственно из динамической библиотеки.
Трансляция программы:
ML /с /coff /DMASM pr72_1.asm LINK /SUBSYSTEM:WINDOWS pr72_1.obj
TASM32 /ml pr72_1.asm IMPLIB pr72_1.lib pr72_1.dll TLINK32 -aa pr72_1.obj
Ранее было сказано, что возможным механизмом связывания является определение адреса процедуры через порядковый номер. Изложим схему того, как это можно сделать. Сначала вы должны сопоставить процедуре, которая будет вызываться из динамической библиотеки, некое двухбайтное число. Это делается посредством строки в DEF-файле:
EXPORTS DLLP1 @1.
Здесь процедуре DLLP1 сопоставляется номер 1. DEF-файлы мы уже использовали при трансляции в TASM. Точно так же их можно использовать и в MASM (ключ /DEF:ИМЯ для программы link). После это производится трансляция, и DLL готова. Теперь при вызове функции GetProcAddress вторым параметром следует указать порядковый номер, точнее двойное слово, младшее слово которого есть порядковый номер, а старшее слово равно нулю. И все будет работать точно так же, как и раньше.
На следующем шаге мы рассмотрим использование общего адресного пространства.