2007. március 1., csütörtök

Memory shared in a Dynamic-Link Library


Problem/Question/Abstract:

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.


Component Download:  http://objecteverywhere.chez.tiscali.fr/SMem.zip

Nincsenek megjegyzések:

Megjegyzés küldése