我想在两个应用程序之间共享数组数据.在我看来,第一个程序创建数组,第二个程序可以从已分配的内存区读取数组.该数组不是动态数组.
我找到了一种使用OpenFileMapping和MapViewOfFile共享指针的方法.我没有运气实现数组共享,我想我还不想使用IPC方法.
是否有可能计划这样的方案(共享阵列)?我的目的是最大限度地减少内存使用和读取数据.
解决方法
我想到了两个应用程序之间共享内存的简短但完整的例子.唯一的选择是控制台应用程序,GUI应用程序至少需要3个文件(DPR PAS DFM).所以我编写了一个小例子,其中一个整数数组使用内存映射文件共享(由页面文件支持,所以我不需要在磁盘上有一个phisical文件来实现).控制台应用程序响应3个命令:
>退出
> 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,SizeOf(TSharedArray),'{C616DDE6-23E2-425C-B871-9E0DA54D96DF}'); if hFileMapping = 0 then RaiseLastOSError else try SharedArray := MapViewOfFile(hFileMapping,FILE_MAP_READ or FILE_MAP_WRITE,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[',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.