Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Scratched my head thinking of what a short-but-complete example of sharing memory between two applications might be. The only option is a console application, GUI applications require a minimum of 3 files (DPR + PAS + DFM). So I cooked up a small example where one integers array is shared using a memory mapped file (backed by the page file so I don't need to have a phisical file on disk for this to work). The console application responds to 3 commands:</p> <ul> <li><strong>EXIT</strong></li> <li><strong>SET NUM VALUE</strong> Changes the value at index <strong>NUM</strong> in the array to <strong>VALUE</strong></li> <li><strong>DUMP NUM</strong> displays the value in the array at index <strong>NUM</strong></li> <li><strong>DUMP ALL</strong> displays the whole array</li> </ul> <p>Of course, the command processing code takes up about 80% of the whole application. To test this compile the following console application, find the executable and <em>start it twice</em>. Go to the first window and enter:</p> <pre><code>SET 1 100 SET 2 50 </code></pre> <p>Go to the second console and enter this:</p> <pre><code>DUMP 1 DUMP 2 DUMP 3 SET 1 150 </code></pre> <p>Go to the first console and enter this:</p> <pre><code>DUMP 1 </code></pre> <p>There you have it, you've just witnessed sharing memory between two applications.</p> <pre><code>program Project2; {$APPTYPE CONSOLE} uses SysUtils, Windows, Classes; type TSharedArray = array[0..10] of Integer; PSharedArray = ^TSharedArray; var hFileMapping: THandle; // Mapping handle obtained using CreateFileMapping SharedArray: PSharedArray; // Pointer to the shared array cmd, s: string; num, value, i: Integer; L_CMD: TStringList; function ReadNextCommand: string; begin WriteLn('Please enter command (one of EXIT, SET NUM VALUE, DUMP NUM, DUMP ALL)'); WriteLn; ReadLn(Result); end; begin try hFileMapping := CreateFileMapping(0, nil, PAGE_READWRITE, 0, SizeOf(TSharedArray), '{C616DDE6-23E2-425C-B871-9E0DA54D96DF}'); if hFileMapping = 0 then RaiseLastOSError else try SharedArray := MapViewOfFile(hFileMapping, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, SizeOf(TSharedArray)); if SharedArray = nil then RaiseLastOSError else try WriteLn('Connected to the shared view of the file.'); cmd := ReadNextCommand; while UpperCase(cmd) &lt;&gt; 'EXIT' do begin L_CMD := TStringList.Create; try L_CMD.DelimitedText := cmd; for i:=0 to L_CMD.Count-1 do L_CMD[i] := UpperCase(L_CMD[i]); if (L_CMD.Count = 2) and (L_CMD[0] = 'DUMP') and TryStrToInt(L_CMD[1], num) then WriteLn('SharedArray[', num, ']=', SharedArray^[num]) else if (L_CMD.Count = 2) and (L_CMD[0] = 'DUMP') and (L_CMD[1] = 'ALL') then begin for i:= Low(SharedArray^) to High(SharedArray^) do WriteLn('SharedArray[', i, ']=', SharedArray^[i]); end else if (L_CMD.Count = 3) and (L_CMD[0] = 'SET') and TryStrToInt(L_CMD[1], num) and TryStrToInt(L_CMD[2], value) then begin SharedArray^[num] := Value; WriteLn('SharedArray[', num, ']=', SharedArray^[num]); end else WriteLn('Error processing command: ' + cmd); finally L_CMD.Free; end; // Requst next command cmd := ReadNextCommand; end; finally UnmapViewOfFile(SharedArray); end; finally CloseHandle(hFileMapping); end; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload