在 Delphi 中的两个应用程序之间共享数据数组 [英] Sharing data array between two applications in Delphi

查看:54
本文介绍了在 Delphi 中的两个应用程序之间共享数据数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在两个应用程序之间共享数组数据.在我看来,第一个程序创建数组,第二个程序可以从已经分配的内存区域读取数组.该数组不是动态数组.

I want to share array data between two applications. In my mind, first program create the array and the second program can read the array from already allocated memory area. The array is not a dynamic array.

我找到了一种使用 OpenFileMappingMapViewOfFile 来共享指针的方法.我没有实现数组共享的运气,我想我还不想使用 IPC 方法.

I found a way to share pointer using OpenFileMapping and MapViewOfFile. I have no luck to implement array sharing and I think i don't want to use IPC method yet.

有没有可能规划这样的方案(共享数组)?我的目的是尽量减少内存使用和快速读取数据.

Is it possible to plan a scheme like this (sharing array)? My purpose is to minimize memory usage and reading data quickly.

推荐答案

想到一个在两个应用程序之间共享内存的简短但完整的示例可能是什么.唯一的选择是控制台应用程序,GUI 应用程序至少需要 3 个文件(DPR + PAS + DFM).因此,我编写了一个小示例,其中使用内存映射文件共享一个整数数组(由页面文件支持,因此我不需要磁盘上的物理文件即可正常工作).控制台应用程序响应 3 个命令:

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:

  • 退出
  • SET NUM VALUE 将数组中索引 NUM 处的值更改为 VALUE
  • DUMP NUM 显示数组中索引 NUM
  • 处的值
  • DUMP ALL 显示整个数组
  • EXIT
  • SET NUM VALUE Changes the value at index NUM in the array to VALUE
  • DUMP NUM displays the value in the array at index NUM
  • DUMP ALL displays the whole array

当然,命令处理代码占整个应用程序的80%左右.为了测试这个编译下面的控制台应用程序,找到可执行文件并启动它两次.转到第一个窗口并输入:

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 start it twice. Go to the first window and enter:

SET 1 100
SET 2 50

转到第二个控制台并输入:

Go to the second console and enter this:

DUMP 1
DUMP 2
DUMP 3
SET 1 150

转到第一个控制台并输入:

Go to the first console and enter this:

DUMP 1

大功告成,您刚刚见证了两个应用程序之间的共享内存.

There you have it, you've just witnessed sharing memory between two applications.

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.

这篇关于在 Delphi 中的两个应用程序之间共享数据数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆