This shows how to use shared memory in a DLL with Delphi 32bit. Use the functions OpenMap and CloseMap.
Any two or more applications or DLLs may obtain pointers to the same physical block of memory this way.
PMapData will point to a 1000 byte buffer in this example, this buffer being initialized to #0's the first time in.
One potential problem is synchronizing access to the memory. You may accomplish this through the use of mutexes:
Call the function LockMap before writing (and reading?) to the memory mapped file.
Be sure to call UnlockMap immediately when done updating.
From: John Crane:
var
HMapping: THandle;
PMapData: Pointer;
const
MAPFILESIZE = 1000;
procedure OpenMap;
var
llInit: Boolean;
lInt: Integer;
begin
HMapping := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
0, MAPFILESIZE, pchar('MY MAP NAME GOES HERE'));
// Check if already exists
llInit := (GetLastError() <> ERROR_ALREADY_EXISTS);
if (hMapping = 0) then
begin
ShowMessage('Can''t Create Memory Map');
Application.Terminate;
exit;
end;
PMapData := MapViewOfFile(HMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if PMapData = nil then
begin
CloseHandle(HMapping);
ShowMessage('Can''t View Memory Map');
Application.Terminate;
exit;
end;
if (llInit) then
begin
// Init block to #0 if newly created
memset(PMapData, #0, MAPFILESIZE);
end
end;
procedure CloseMap;
begin
if PMapData <> nil then
UnMapViewOfFile(PMapData);
if HMapping <> 0 then
CloseHandle(HMapping);
end;
var
HMapMutex: THandle;
const
REQUEST_TIMEOUT = 1000;
function LockMap:Boolean;
begin
Result := true;
HMapMutex := CreateMutex(nil, false,
pchar('MY MUTEX NAME GOES HERE'));
if HMixMutex = 0 then
begin
ShowMessage('Can''t create map mutex');
Result := false;
end
else
begin
if WaitForSingleObject(HMapMutex,REQUEST_TIMEOUT)
= WAIT_FAILED then
begin
// timeout
ShowMessage('Can''t lock memory mapped file');
Result := false;
end
end
end;
procedure UnlockMap;
begin
ReleaseMutex(HMixMutex);
CloseHandle(HMixMutex);
end;