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

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

问题描述

我想两个应用程序之间共享阵列的数据。在我的脑海里,第一个程序创建阵列和第二程序可以读取已分配的内存区域的阵列。阵列不是动态数组。

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.

我找到了一种方法使用 OpenFileMapping MapViewOfFile 共享指针。我没有运气来实现阵列的共享,我想我不希望使用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:


  • 退出

  • 设置NUM值更改索引的 NUM 数组中的值的

  • DUMP NUM 显示索引数组中的值 NUM

  • 转储全部显示整个阵列

  • 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

当然,命令处理code占据了整个应用程序的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.

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

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