Пятница, 18.07.2025, 20:38 Приветствую Вас Гость

On-line: Книги, учебники, статьи

Главная | Регистрация | Вход | RSS

Глава 3. Создание динамических библиотек(4)

Трансляция программ на Рис. 3.3.6.
MASM32:

 ml /c /coff /DMASM dllex3.asm
 rc dllex3.rc
 link /subsystem:windows dllex3.obj dllex3.res

 ml /c /coff /DMASM dll3.asm
 rc dll3.rc
 link /subsystem:windows /DLL /ENTRY:DLLENTRY dll3.obj dll3.res
TASM32:
 tasm32 /ml dllex3.asm
 brcc32 dllex3.rc
 tlink32 -aa -Tpe dllex3.obj,,,,,dllex3.res

 tasm32 /ml dll3.asm
 brcc32 dll3.rc
 tlink32 -aa -Tpd dll3.obj,,,,dll3.def,dll3.res

Содержимое файла dll3.def:

EXPORTS SETIC

Как мы уже не раз с Вами убеждались, динамическая библиотека становится частью программы, обладая вместе с процессом всеми ее возможностями. Так, при помощи функций GetMessage и PeekMessage она может получать сообщения, предназначенные для процесса. Если Вы хотите создать в динамической библиотеке окно, то Вам следует воспользоваться идентификатором вызвавшей динамическую библиотеку программы.

V

Рассмотрим теперь вопрос о том, как используют динамическую библиотеку различные экземпляры приложения или разные процессы. Если Вы немного знакомы с принципом функционирования операционной системы Windows, то, возможно, такая постановка вопроса у Вас вызовет недоумение. "У каждого приложения свое адресное пространство, куда загружается динамическая библиотека", - скажете Вы. Конечно, это не совсем рационально, но зато безопасно. О памяти мы еще подробно будем говорить в гл. 3.6, здесь же заметим, что, вообще говоря, приложение может инициализировать так называемую разделяемую память. Мы вернемся к этому вопросу еще неоднократно, сейчас же рассмотрим этот вопрос чисто технически, применительно к динамическим библиотекам. Рассмотрим конкретную ситуацию. Запускаемое приложение загружает динамическую библиотеку и вызывает процедуру из динамической библиотеки, которая меняет данные, расположенные опять же в динамической библиотеке. Запустим теперь второй экземпляр приложения. Оно загружает еще один экземпляр динамической библиотеки. Могут быть ситуации, когда желательно, чтобы второе запущенное приложение "знало", что по команде первого приложения данные уже изменились. Ясно, что в этом случае данные, которыми оперирует динамическая библиотека, должны быть общими. Технически это делается очень просто. У редактора связей LINK есть опция /section: имя, атрибуты, которая позволяет объявить явно свойства данной секции. Мы будем говорить о секциях далее, здесь же достаточно сказать, секция - это просто сегмент в старом понимании. В редакторе связей TLINK32 то же действие можно осуществить с помощью файла .DEF.

Представленные на Рис. 3.3.7 программы весьма просты. По сути, они лишь иллюстрируют возможности использования разделяемой памяти. Перед выходом из процедуры динамической библиотеки изменяется строка, хранящаяся в разделяемой секции памяти. При этом приложение не заканчивает своей работы. При запуске второго экземпляра приложения на экран выводится уже измененное первым приложением значение строки.

; динамическая библиотека DLL4.ASM
.386P
; плоская модель
IFDEF MASM
 .MODEL FLAT, stdcall
ELSE
.MODEL FLAT
ENDIF

PUBLIC DLLP1

IFDEF MASM
; MASM
; прототипы внешних процедур
 EXTERN MessageBoxA@16:NEAR 
; директивы компоновщику для подключения библиотек
 includelib c:\masm32\lib\user32.lib
 includelib c:\masm32\lib\kernel32.lib
ELSE
; TASM
 EXTERN MessageBoxA:NEAR
 MessageBoxA@16 = MessageBoxA
 includelib c:\tasm32\lib\import32.lib
ENDIF
;--------------------------------------------------

; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
 TEXT DB "В динамической библиотеке",0
 MS DB "Сообщение",0
_DATA ENDS

; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
; [EBP+10H] ; резервный параметр
; [EBP+0CH] ; причина вызова
; [EBP+8] ; идентификатор DLL-модуля
DLLENTRY:
 MOV EAX,1
 RET 12
;------------------
;адреса параметров
DLLP1 PROC EXPORT
 PUSH EBP
 MOV EBP,ESP
 PUSH 0
 PUSH OFFSET MS
 PUSH OFFSET TEXT
 PUSH 0
 CALL MessageBoxA@16
; изменим строку, расположенную в разделяемой памяти
 MOV TEXT,'И'
 MOV TEXT+1,'з'
 POP EBP
 RET
DLLP1 ENDP
_TEXT ENDS
END DLLENTRY

; основной модуль DLLEX4.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
; директивы копоновщику для подключения библиотек
 includelib c:\tasm32\lib\import32.lib
 EXTERN GetProcAddress:NEAR
 EXTERN LoadLibraryA:NEAR
 EXTERN FreeLibrary:NEAR
 EXTERN ExitProcess:NEAR
 EXTERN MessageBoxA:NEAR
 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 'DLL4.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'
; [EBP+10H] ; резервный параметр
; [EBP+0CH] ; причина вызова
; [EBP+8] ; идентификатор DLL-модуля
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:
 CALL EAX
 PUSH 0
 PUSH OFFSET MS
 PUSH OFFSET MS
 PUSH 0
 CALL MessageBoxA@16
; закрыть библиотеку
; библиотека автоматически закрывается также
; при выходе из программы
 PUSH OFFSET NAMEPROC
 PUSH HLIB
 CALL FreeLibrary@4
; выход
_EXIT:
 PUSH 0
 CALL ExitProcess@4
_TEXT ENDS
END START

Рис. 3.3.7. Пример использования разделяемой памяти в динамической библиотеке.

Трансляция программ на Рис. 3.3.7.
MASM32.

 ml /c /coff /DMASM dll4.asm
 link /subsystem:windows /DLL /section:.data,SRW dll4.obj
 ml /c /coff /DMASM dllex4.asm
 link /subsystem:windows dllex4.obj

Атрибуты опции SECTION: S-SHARED, R-READ, W-WRITE.

TASM32.

 tasm32 /ml dll4.asm
 tlink32 -aa -Tpd dll4.obj,,,,dll4.def
 tasm32 /ml dllex4.asm
 tlink32 -aa dllex4.obj

Содержимое DEF-файла:

SECTIONS .DATA SHARED
EXPORTS DLLP1


Вход на сайт
Поиск
Календарь
«  Июль 2025  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031
Архив записей
Наш опрос
Как Вам удобнее??
Всего ответов: 341
Мини-чат
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0