© Терехов А В. 2002
CreateFileMapping или создание объекта файлового отображения.
Если вспомнить написанное выше, то страничный файл операционной системы используется
как расширение памяти. Под расширением понимается процесс подкачки (swap) ОЗУ, вызывающийся
системой по мере необходимости. Таким образом, создав объект файлового отображения, связанный
со страничным свап-файлом, мы получим в качестве результата выделение глобально
доступной памяти. Так как эта память является общедоступной, то любой другой
процесс, создавший экземпляр объекта файлового отображения, будет иметь доступ к этим данным.
Function CreateFileMapping(hFile: THandle; lpFileMappingAttributes: PSecurityAttributes; flProtect, dwMaximumSizeHigh, dwMaximumSizeLow: DWORD; lpName: PChar): THandle;hFile - файловый идентификатор - в результате присвоения этому аргументу значения $FFFFFFFF или определенной в Windows.pas константы MAXDWORD мы свяжем создаваемый объект файлового отображения со страничным свап-файлом.
MapViewOfFile или подключение объекта файлового отображения к адресному пространству.
Будучи созданным при помощи функции CreateFileMapping, объект файлового отображения должен отображать
связанный с ним файл (в нашем случае страничный свап-файл операционной системы) в адресное
пространство процессов. В результате выполнения MapViewOfFile мы получим начальный адрес нужных
нам данных.
Function MapViewOfFile(hFileMappingObject: THandle; dwDesiredAccess: DWORD; dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap: DWORD): Pointer;hFileMappingObject - описатель (хэндл) созданного выше объекта файлового отображения.
UnMapViewOfFile или прекращение отображения данных.
Для отключения от текущего процесса объекта файлового отображения используется функция
UnMapViewOfFile.
Function UnMapViewOfFile(lpBaseAddress: Pointer): Boolean;lpBaseAddress - в этот аргумент должно быть помещено значение, возвращаемое функцией MapViewOfFile.
CloseHandle или закрытие объекта файлового отображения.
Для уничтожения объекта файлового отображения и освобождения памяти используется функция
CloseHandle.
Function CloseHandle(hFileMapObj:THandle):Boolean;hFileMapObj - описатель (хэндл) объекта файлового отображения, полученный в результате выполнения функции CreateFileMapping.
Для правильного завершения работы с объектом файлового отображения вначале следует применить функцию UnMapViewOfFile, а затем CloseHandle.
Прототипы функций (кроме CloseHandle) и необходимые константы определены в файле Windows.pas. Этот файл находится в созданной при установке Delphi директории \Borland\Delphi_X\Source\Rtl\Win
Однако "чистая теория" не дает полного представления о том, как все может выглядеть на практике. Поэтому рассмотрим небольшой практический пример.
unit Main;
 
interface
 
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ExtCtrls;
 
type
    TForm1 = class(TForm)
    edVariable: TEdit;
    lbEnterValues: TLabel;
    bbOK: TBitBtn;
    bbExit: TBitBtn;
    lbShowValue: TLabel;
    lbVariable: TLabel;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure bbExitClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure bbOKClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
 
var
    Form1: TForm1;
//глобальные переменные
    hFileMapObj:THandle;//описатель FaleMapping
    lpBaseAddress:PChar;//"указатель" (см. выше) на начальный адрес данных
implementation
 
{$R *.DFM}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
//создадим FileMapping с именем MySharedValue
//и передадим его хэндл в глобальную переменную hFileMapObj
    hFileMapObj:=CreateFileMapping(MAXDWORD,Nil,PAGE_READWRITE,0,4,'MySharedValue');
    If (hFileMapObj=0) Then
//ошибочка вышла
        ShowMessage('Не могу создать FileMapping!')
    Else
//подключим FileMapping к адресному пространству
//и получим начальный адрес данных
        lpBaseAddress:=MapViewOfFile(hFileMapObj,FILE_MAP_WRITE,0,0,0);
    If lpBaseAddress=Nil Then
//ошибочка вышла
        ShowMessage('Не могу подключить FileMapping!');
end;
 
procedure TForm1.bbExitClick(Sender: TObject);
begin
//закроем форму
    Close;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//кое-что надо сделать при закрытии формы:
//отключим FileMapping от адресного пространства
    UnMapViewOfFile(lpBaseAddress);
//освободим объект FileMapping
    CloseHandle(hFileMapObj);
//теперь форму можно закрыть
    Action:=caFree;
end;
 
procedure TForm1.bbOKClick(Sender: TObject);
begin
//поместим в адресное пространство свои данные
//переменная типа PChar имеет в конце завершающий #0, значит при считывании данных
//система сама сможет определить, где находится конец нужных данных
    StrPCopy(lpBaseAddress,edVariable.Text);
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
//считаем нужные данные, обратившись по начальному адресу
//данных адресного пространства FileMapping
    lbVariable.Caption:=PChar(lpBaseAddress);
end;
 
end.