1. Overview
In Win32, by using image files to implement shared files or shared memory blocks between processes, if you take advantage of the same image name or file handle, different processes can read or write a file or the same block of memory data through a pointer and treat it as part of the in-process address space
When windows9x/nt/200 loads files into memory, a special global memory area is used. Within the region, the virtual memory address of the application corresponds to the location of the response in the file, because all processes congratulate a global memory region that is used to store the image file, so when two processes load the same module (application exe or DLL file), they actually enjoy their execution code in memory
The memory image file can map a file, a specified area in a file, or a specified block of memory, where the data can be directly accessed with memory read and write instructions, rather than frequent calls to the I/O system functions such as ReadFile or WriteFile, which improves file access speed and efficiency
2. Example code 2.1. Share data between two EXE
Send data side
UnitUnit1;InterfaceusesWinapi.windows, Winapi.messages, System.sysutils, System.variants, system.classes, Vcl.graphics, Vcl.Controls, Vcl.forms, Vcl.dialogs, Vcl.stdctrls;ConstWm_data = Wm_user +1024x768;typePsharemem = ^tpsharemem; Tpsharemem =Record //Shared dataData:Array[0..255] of Char;End; TForm1 =class(Tform) Btn1:tbutton;procedureBtn1click (Sender:tobject);procedureFormdestroy (Sender:tobject);procedureFormcreate (Sender:tobject);Private {Private declarations} Public {public declarations} End;varForm1:tform1; Pshare:psharemem;Implementation{$R *.DFM}varHmapping:thandle; Hmapmutex:thandle;ConstMap_file_size = +; Request_time_out = +;{Open build shared memory}procedureOpenmap;begin {Create an image file}Hmapping: = CreateFileMapping ($FFFFFFFF, Nil, Page_readwrite,0, SizeOf (Tpsharemem), PChar (' MapName '));ifHmapping =0 Then beginShowMessage (' cannot create memory image file ');Exit End;{Map the image file to the address space of the process}Pshare: = Psharemem (MapViewOfFile (hmapping, File_map_all_access,0,0,0));ifPshare =Nil Then beginCloseHandle (hmapping); ShowMessage (' The image file does not exist in memory '); Application.terminate;Exit End;End;{close shared memory}procedureClosemap;begin ifPshare <>Nil Then begin {Undoing an image file from the address space of the process}UnmapViewOfFile (Pshare);End;ifHmapping <>0 Then begin {Close image file}CloseHandle (hmapping);End;End;{Create Mutex}functionLockmap:Boolean;beginResult: =True; Hmapmutex: = CreateMutex (Nil,False, PChar (' My MUTEX NAME coes here '));ifHmapmutex =0 Then beginShowMessage (' cannot create mutex object '); Result: =False;End Else begin ifWaitForSingleObject (Hmapmutex, request_time_out) = wait_failed Then beginShowMessage (' cannot yoke on mutually exclusive objects '); Result: =False;End;End;End;procedureUnlockmap ();begin {release, close mutex}ReleaseMutex (Hmapmutex); CloseHandle (Hmapmutex);End;procedureTform1.btn1click (Sender:tobject);varStr:pchar;beginstr: = PChar (' Simple shared memory example ');//Copy data to shared memoryCopyMemory (@ (pshare^. Data), str, Length (str) *sizeof (Char));//Send a message indicating that there is dataPostMessage (FINDWINDOWW (Nil,' Form2 '), Wm_data,1,2);End;procedureTform1.formcreate (Sender:tobject);beginOpenmap (); Lockmap ();End;procedureTform1.formdestroy (Sender:tobject);beginUnlockmap (); Closemap ();End;End.
- The length (str) used by CopyMemory in the book "Deep Windows Programming under Delphi", but after the addition of the Unicode character support in Delphi, will result in insufficient length calculations, sending only half the characters
- Refer to the case of the blog with the ByteLength function to solve, but also some people say that the bytelength function can only the Unicode string byte length, if you want to calculate the ANSI string, the result will be twice times the correct value
- Final Solution:
Length(str)*SizeOf(Char)
Receiving Data end
UnitUnit2;InterfaceusesWinapi.windows, Winapi.messages, System.sysutils, System.variants, system.classes, Vcl.graphics, Vcl.Controls, Vcl.forms, Vcl.dialogs, Vcl.stdctrls;Const //Custom messageWm_data = Wm_user +1024x768;typePsharemem = ^tpsharemem; Tpsharemem =Record //Shared data note to the same definition as the sending data segmentData:Array[0..255] of Char;End;typeTForm2 =class(Tform) Mmo1:tmemo; Btn1:tbutton;procedureFormcreate (Sender:tobject);procedureBtn1click (Sender:tobject);Private {Private declarations} Public {public declarations} procedureGetshareinfo (varMsg:tmessage); Message wm_data;End;varForm2:tform2; Pshare:psharemem; Maphandle:thandle;Implementation{$R *.DFM}{TForm2}{process Wm_data custom message}procedureTform2.btn1click (Sender:tobject);beginCloseHandle (Maphandle);End;procedureTform2.formcreate (Sender:tobject);beginMaphandle: = openfilemapping (File_map_write,False, PChar (' MapName '));ifMaphandle =0 Then beginShowMessage (' cannot locate memory image File Block ');End;{Map the image file to the address space of the process}Pshare: = Psharemem (MapViewOfFile (Maphandle, File_map_all_access,0,0,0));ifPshare =Nil Then beginCloseHandle (Maphandle); ShowMessage (' cannot display image file '); Application.terminate;Exit;End; Fillchar (pshare^, SizeOf (TPSHAREMEM),0);End;procedureTform2.getshareinfo (varMsg:tmessage);begin {If the parameter sent by the sending data side is 1} ifMsg.lparam =2 Then begin //Display data in shared memoryMmo1.Text: = pshare^. Data;End; Pshare: = Psharemem (MapViewOfFile (Maphandle, File_map_all_access,0,0,0));ifPshare =Nil Then beginCloseHandle (Maphandle); ShowMessage (' cannot display image file '); Application.terminate;Exit;End; Fillchar (pshare^, SizeOf (TPSHAREMEM),0);End;End.
Data sharing between processes