Цель работы: практическое знакомство со средствами передачи данных между процессами, (Interprocess Communications-IPC), выполняющимися на одном компьютере.
Краткие теоретические сведения
В данной работе будут рассмотрены только два метода IPC:
- использование буфера обмена (Clipboard);
- файлы, проецируемые в память.
Использование буфера обмена
Буфер обмена (clipboard) в основном используется для удобства пользователей и редко используется как метод IPC. В Delphi для вырезания, копирования и вставки данных используется класс Tclipboard, объявленный в модуле Clipbrd. Данный модуль необходимо добавить в оператор uses.
Класс Tclipboard имеет следующие свойства:
- Это свойство, имеющее тип String, используется для копирования текста в буфер обмена и вставки его из буфера обмена. Поскольку AsText представляет собой строку Pascal, ее длина ограничена 255 символами. При работе с текстом большего объема следует использовать методы SetTextBuf и GetTextBuf.
В буфере обмена могут находиться данные различных типов. Если буфер обмена содержит текст, выражение Clipboard.HasFormat (cf_Text) соответствует истине.
Для растровой графики используйте тип сf_Bitmap.
- Свойство типа Integer равно количеству элементов в массиве Formats.
- Массив значений, имеющих тип Word и представляющих собой зарегистрированные форматы данных буфера обмена.
Для копирования графики в буфер обмена следует использовать метод Assign. Например
Clipboard.Assign (Image1.Pictire); // копирование в буфер обмена
Image2.Picture.Assign (Clipboard); // копирование из буфера обмена
Использование файлов, проецируемых в память
Ниже приведен текст DLL, используемой для создания области в страничном файле, доступ к которой могут иметь несколько процессов.
library ShareHeap;
uses
SysUtils, Classes, Windows;
const MaxSize =1000;
var
hObjHand : Thandle;
pGMem : pointer;
procedure UnmapMemory;
begin
if Assigned (pGMem) then
begin
UnMapViewOfFile (pGMem);
pGmem := nil;
end;
if hObjHand >0 then CloseHandle (hObjHand);
hObjHand :=0;
end;
procedure MapMemory (dwAllocSize : dword);
begin
hObjHand :=CreateFileMapping(MaxDword, nil,
PAGE_READWRITE,0, dwAllocsize,Pchar(‘Gmem’));
if (hObjHand = 0) then
Raise Exception.Create(‘Не создан file-mapping Obj’);
pGMem := MapViewOffile(HobjHand,File_Map_Write,0,0,1);
if not Assigned(pgmem) then
begin
UnMapMemory;
Raise Exception.Create(‘Could not map file’);
end;
end;
procedure DLLMain (dwAct : Dword);
begin
case dwAct of
dll_Process_Attach :
begin
pgMem := nil;
hObjHand :=0;
MapMemory(MaxSize);
end;
dll_Process_Detach:
UnmapMemory;
end;
end;
// получение блока памяти из страничного файла
function GetBlock : pointer; StdCall;
begin
result := pGmem;
end;
exports GetBlock;
begin
DLLProc := @DLLMain;
DLLMain (dll_Process_Attach);
end.
Ниже приведен пример фрагмента текста приложения, использующего функцию GetBlock из библиотеки ShareHeap для передачи строки символов между приложениями.
var
pcBuf : Pchar;
function GetBlock : pointer; stdcall;
external ‘SHAREHEAP.DLL’;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
pcbuf := GetBlock;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.GetTextBuf(pcBuf,Length(Edit1.Text)+1);
// Memo1.SetTextBuf (pcbuf); // timer1.Enabled:=True;
// edit2.SetTextBuf(pcBuf);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Memo1.SetTextBuf (pcbuf);
// edit2.SetTextBuf(pcBuf); // timer1.Enabled:=false;
end;
Порядок выполнения работы
- Написать приложение, выполняющее занесение в буфер обмена текста и графики и приложение, получающее из буфера обмена находящиеся в нем данные.
- Создать DLL для экспорта функции получения блока данных в страничном файле.
- Написать приложение для обмена данными с использованием созданной в п.2 функции GetBlock.
Отчет о работе
Для отчета о работе используются экранные формы разработанных в п.1 и п.3 приложений.