Title: Memory shared in a Dynamic-Link Library
Question: How several processes can share memory to cooperate ?
Answer:
The unit bellow shows how use a file-mapping object to set up memory that can be shared by processes that load the DLL.
The shared DLL memory persists only as long as the DLL is loaded.
This unit is the translation of the DLLSHMEM.C example from the Win32 Developer's Reference help file (see DLLSHMEM)
The SetSharedMem and GetSharedMem functions must be exported in a dll Delphi project.
If we can't create the file-mapped shared memory ExitCode variable is set to 1 or 2.
Tested with Delphi 6, under Windows 2000.
unit SharedMem;
// Using Shared Memory in a Dynamic-Link Library
//
// This unit shows how use a file-mapping object to set up memory that can be shared by processes that load the DLL.
// The shared DLL memory persists only as long as the DLL is loaded.
//
// This unit is the translation of the DLLSHMEM.C example from the W32 Developer's Reference help file (see DLLSHMEM)
//
// The SetSharedMem and GetSharedMem functions must be exported in a dll Delphi project.
// If we can't create the file-mapped shared memory ExitCode variable is set to 1 or 2.
// Tested with Delphi 6, under Windows 2000.
//
// Written by Bertrand Goetzmann (http://www.object-everywhere.com)
// Keywords : Shared-Memory DLL CreateFileMapping MapViewOfFile UnmapViewOfFile
interface
procedure SetSharedMem(lpszBuf: PChar);
procedure GetSharedMem(lpszBuf: PChar; cchSize: Integer);
implementation
uses Windows, SysUtils;
// Using Shared Memory in a Dynamic-Link Library
// The DLL sets up shared memory using a named file-mapping object.
const
SHMEMSIZE = 4096;
var
hMapObject: THandle;
lpvMem: Pointer; // pointer to shared memory
procedure Init;
var
fInit: Boolean;
begin
hMapObject := 0; // handle to file mapping
// The DLL is loading due to process
// initialization or a call to LoadLibrary.
// Create a named file mapping object.
hMapObject := CreateFileMapping(
$FFFFFFFF, // use paging file
nil, // no security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
SHMEMSIZE, // size: low 32-bits
'dllmemfilemap'); // name of map object
if hMapObject = 0 then
begin
ExitCode := 1;
Exit;
end;
// The first process to attach initializes memory.
fInit := GetLastError ERROR_ALREADY_EXISTS;
// Get a pointer to the file-mapped shared memory.
lpvMem := MapViewOfFile(
hMapObject, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if lpvMem = nil then
begin
ExitCode := 2;
Exit;
end;
// Initialize memory if this is the first process.
if fInit then
FillChar(lpvMem^, SHMEMSIZE, 0);
end;
procedure Terminate;
begin
// Unmap shared memory from the process's address space.
if lpvMem nil then
UnmapViewOfFile(lpvMem);
// Close the process's handle to the file-mapping object.
if hMapObject 0 then
CloseHandle(hMapObject);
end;
// SetSharedMem sets the contents of shared memory.
procedure SetSharedMem(lpszBuf: PChar);
begin
Move(lpszBuf^, lpvMem^, StrLen(lpszBuf));
end;
// GetSharedMem gets the contents of shared memory.
procedure GetSharedMem(lpszBuf: PChar; cchSize: Integer);
begin
Move(lpvMem^, lpszBuf^, cchSize);
end;
initialization
Init;
finalization
Terminate;
end.