Ceci est une ancienne révision du document !


Mémoire partagée

Utilisation d'une classe TTICSharedMemory

Ci dessous un exemple de données partagées entre deux applications Windows.
Un serveur avec un TEdit, qui modifie la mémoire partagé dés qu'on modifie la valeur du TEdit.
Un Client, qui affiche toutes les secondes la valeur de la donnée partagée.

uTICSharedMemory

Cette unité contient le code de l'object TTICSharedMemory

uTICSharedMemory
unit uTICSharedMemory;
 
{$mode ObjFPC}{$H+}
 
interface
 
uses
  Windows;
 
type
 
  { TTICSharedMemory }
 
  TTICSharedMemory = class
  private
    FPointer:   Pointer;
    FLastError: DWord;
    FHandle:    THandle;
    procedure FreeHandle;
  public
    // AName = l'identifiant du fichier partagé en mémoire
    // ASize = la taille totale des données partagées
    constructor Create(AName: PChar; ASize: integer);
 
    destructor Destroy; override;
    property LastError: DWord read FLastError;
 
   // Pointer = l'adresse de la donnée partagée
    property Pointer: pointer read FPointer;
  end;
 
implementation
 
{ TTICSharedMemory }
 
procedure TTICSharedMemory.FreeHandle;
begin
  if FHandle <> 0 then
  begin
    CloseHandle(FHandle);
    FHandle := 0;
  end;
end;
 
constructor TTICSharedMemory.Create(AName: PChar; ASize: integer);
begin
  FHandle    := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE,
    0, ASize, AName);
  FLastError := GetLastError;
 
  if FHandle > 0 then
  begin
    FPointer := MapViewOfFile(FHandle, FILE_MAP_WRITE, 0, 0, 0);
    if not assigned(FPointer) then FreeHandle;
  end;
end;
 
destructor TTICSharedMemory.Destroy;
begin
  if assigned(FPointer) then
  begin
    UnmapViewOfFile(FPointer);
    FPointer := nil;
  end;
  FreeHandle;
  inherited;
end;
 
end.                                 

Le Client

Cette unité contient le code du client.
C'est un TForm avec un TMemo et un TTimer.
Toutes les secondes il accéde a la mémoire partagé et affiche son contenu dans le TMemo

uFormClient.pas
unit uFormClient;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  SysUtils,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  StdCtrls,
  ExtCtrls,
  uTICSharedMemory;
 
type
 
  // La structure qui sera échangée entre les deux applications
  TDatas = packed record
    Text: shortstring;
    Size: integer;
    Date: TDateTime;
  end;
 
  PDatas = ^TDatas;
 
  { TFormClient }
 
  TFormClient = class(TForm)
    Memo:   TMemo;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    FSMem:   TTICSharedMemory;
    FPDatas: PDatas;
  public
 
  end;
 
var
  FormClient: TFormClient;
 
implementation
 
{$R *.lfm}
 
{ TFormClient }
 
procedure TFormClient.FormCreate(Sender: TObject);
begin
  FSMem   := TTICSharedMemory.Create('shmemtest', sizeof(TDatas));
  FPDatas := FSMem.Pointer;
end;
 
procedure TFormClient.Timer1Timer(Sender: TObject);
begin
  Memo.Lines.Add(DateTimeToStr(FPDatas^.Date));
  Memo.Lines.Add(FPDatas^.Text);
  Memo.Lines.Add('Longueur:%d', [FPDatas^.Size]);
end;
 
end.

Le Serveur

Un TForm contenant un TEdit.
Dés que l'on modifie le TEdit il met a jour la mémoire partagée.

uFormServer.pas
unit uFormServer;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  uTICSharedMemory;
 
type
 
  // Structure de données partagée
  TDatas = packed record
    Text: shortstring;
    Size: integer;
    Date: TDateTime;
  end;
 
  PDatas = ^TDatas;
 
  { TFormServer }
 
  TFormServer = class(TForm)
    Edit1: TEdit;
    procedure Edit1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FPDatas: PDatas;
    FSMem : TTICSharedMemory;
  public
 
  end;
 
var
  FormServer: TFormServer;
 
implementation
 
{$R *.lfm}
 
{ TFormServer }
 
procedure TFormServer.FormCreate(Sender: TObject);
begin
  FSMem:=TTICSharedMemory.Create('shmemtest',sizeof(TDatas));
  FPDatas:=FSMem.Pointer;
end;
 
procedure TFormServer.FormDestroy(Sender: TObject);
begin
  FSMem.Free;
end;
 
procedure TFormServer.Edit1Change(Sender: TObject);
begin
  // Modification de la mémoire partagée
  FPDatas^.Text:=Edit1.Text+#0;
  FPDatas^.Size:=length(Edit1.Text);
  FPDatas^.Date:=now;
end;
 
 
end.              

A voir

Vous pourriez laisser un commentaire si vous étiez connecté.