[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]

    From: johnnysc@ix.netcom.com (John Crane)

    Sharing Memory Mapped Files... Check out the following code:

    --------------------------------------------------------------------------------

    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 begin
        UnMapViewOfFile(PMapData);
      end;
      if HMapping <> 0 then begin
        CloseHandle(HMapping);
      end;
    end;

    --------------------------------------------------------------------------------

    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. Here's an example of that:

    --------------------------------------------------------------------------------

    { Call LockMap before writing (and reading?) to the memory mapped file.  Be sure to call UnlockMap immediately when done updating. }

    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;

    --------------------------------------------------------------------------------

    Please excuse my unnecessary begin..end's. I come from a Clipper background, and I prefer to see my logic blocks capped off with end's - easier to follow.

[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]