| ||
Now, it's time to consider how different instances of the same application or different processes use the DLL. If you are acquainted with the principles of Windows operation, then such a formulation may stun you. You might say: Every process has its own address space, in which the DLL is loaded. Naturally, this isn't the most efficient approach; however, it is safe. The use of memory will be covered in detail in Chapter 19, but here it is necessary to point out that the application generally can initialize so-called shared memory. I'll return to this problem later and more than once. For the moment, however, consider this problem in relation to DLLs. Consider a practical situation: Suppose that the application loads a DLL and calls a procedure from there, which modifies the data located in that DLL. Now, suppose that the user starts the second instance of the same application. It will also load an instance of the same DLL. It might be desirable to inform the second instance of the application that the DLL data have been changed by the command from the first instance of the same application. Naturally, in this case the data, over which the DLL operates, must be shared. Technically, this is easy to implement. The LINK program has the following option: /section : name , attributes . This allows you to explicitly declare the properties of this section. In this interpretation, the section is simply a segment. Using TLINK32, the same result can be obtained using the DEF file.
The programs presented in Listing 16.6 to illustrate this idea are very simple. Actually, they only demonstrate the use of the shared memory. Before exiting the DLL procedure, the string stored in the shared memory section is modified. The application doesn't terminate its execution. When the next application instance is started, the string modified by the first application instance will be displayed.
; The DLL4.ASM library .586P ; Flat memory model IFDEF MASM .MODEL FLAT, stdcall ELSE .MODEL FLAT ENDIF PUBLIC DLLP1 IFDEF MASM ; MASM ; Prototypes of external procedures EXTERN MessageBoxA@16:NEAR ; INCLUDELIB directives for the linker 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 _DATA SEGMENT TEXT DB "String in a DLL", 0 MS DB "Message", 0 _DATA ENDS ; Code segment _TEXT SEGMENT ; [EBP+10H] ; Reserved parameter ; [EBP+0CH] ; Cause of call ; [EBP+8] ; DLL module identifier DLLENTRY: MOV EAX, 1 RET 12 ;------------------- ; Addresses of parameters DLLP1 PROC EXPORT PUSH EBP MOV EBP, ESP PUSH 0 PUSH OFFSET MS PUSH OFFSET TEXT PUSH 0 CALL MessageBoxA@16 ; Modify the string located in the shared memory MOV TEXT, '0' MOV TEXT+1, 'f' POP EBP RET DLLP1 ENDP _TEXT ENDS END DLLENTRY ; The DLLEX4.ASM main module that calls ; a procedure from the DLL .586P ; Flat memory model .MODEL FLAT, stdcall ; Constants ; Prototypes of external procedures IFDEF MASM ; MASM EXTERN GetProcAddress@8: NEAR EXTERN LoadLibraryA@4:NEAR EXTERN FreeLibrary@4:NEAR EXTERN ExitProcess@4:NEAR EXTERN MessageBoxA@16:NEAR ; INCLUDELIB directives for the linker includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE ; INCLUDELIB directives for the linker 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 _DATA SEGMENT TXT DB 'DLL error', 0 MS DB 'Message', 0 LIBR DB 'DLL4.DLL', 0 HLIB DD ? IFDEF MASM NAMEPROC DB '_DLLP1@O', 0 ELSE NAMEPROC DB 'DLLP1', 0 ENDIF _DATA ENDS ; Code segment _TEXT SEGMENT ; [EBP+10H] ; Reserved parameter ; [EBP+0CH] ; Cause of the call ; [EBP+8] ; DLL module identifier START: ; Load the library PUSH OFFSET LIBR CALL LoadLibraryA@4 CMP EAX, 0 JE _ERR MOV HLIB, EAX ; Get the address PUSH OFFSET NAMEPROC PUSH HLIB CALL GetProcAddress@8 CMP EAX, 0 JNE YES_NAME ; Error message _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 ; Close the library ; The library is automatically closed ; when exiting the program PUSH OFFSET NAMEPROC PUSH HLIB CALL FreeLibrary@4 ; Exit _EXIT: PUSH 0 CALL ExitProcess@4 _TEXT ENDS END START
To translate this program, issue the following commands using MASM32:
ml /c /coff /DMASM dll4.asm link /subsystem:windows /DLL /section:.data, SRW dll2.obj ml /c /coff /DMASM dllex4.asm link /subsystem:windows dllex4.obj
Attributes of the SECTION option are S-SHARED, R-READ , and W-WRITE . Issue the following commands using TASM32:
tasm32 /ml dll4.asm tlink32 -aa -Tpd dll4.obj,,,,dll4.def tasm32 /ml dllex4.asm tlink32 -aa dllex4.obj
The contents of the DEF file are as follows :
SECTIONS .DATA SHARED EXPORTS DLLP1
| ||