Почесал голову, размышляя о том, каким может быть короткий, но полный пример совместного использования памяти между двумя приложениями.Единственным вариантом является консольное приложение, приложения с графическим интерфейсом требуют минимум 3 файла (DPR + PAS + DFM).Поэтому я подготовил небольшой пример, в котором один массив целых чисел используется совместно с отображенным в память файлом (на основе файла подкачки, поэтому мне не нужно иметь физический файл на диске, чтобы это работало).Консольное приложение отвечает на 3 команды:
- EXIT
- SET NUM VALUE Изменяет значение в индексе NUM в массиве VALUE
- DUMP NUM отображает значение в массиве с индексом NUM
- DUMP ALL отображает весь массив
Конечно, код обработки команд занимает около 80% всего приложения.Чтобы проверить это, скомпилируйте следующее консольное приложение, найдите исполняемый файл и дважды запустите его .Перейдите к первому окну и введите:
SET 1 100
SET 2 50
Перейдите ко второй консоли и введите следующее:
DUMP 1
DUMP 2
DUMP 3
SET 1 150
Перейдите к первой консоли и введите следующее:
DUMP 1
Вот оно, вы только что стали свидетелями разделения памяти между двумя приложениями.
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) <> '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.