Exemple d'objet distant

De RAD Studio
Aller à : navigation, rechercher

Remonter à Utilisation de types non scalaires dans des interfaces invocables


Cet exemple montre comment créer un objet distant pour un paramètre sur une interface invocable où vous utiliseriez autrement une classe existante. Dans cet exemple, la classe existante est une liste de chaînes (TStringList). Pour rester de taille raisonnable, cet exemple ne reproduit pas la propriété Objects de la liste de chaînes.

Comme la nouvelle classe n'est pas scalaire, elle dérive de TRemotable plutôt que de TRemotableXS. Elle inclut une propriété publiée pour chaque propriété de la liste de chaînes que vous voulez communiquer entre le client et le serveur. Chacune de ces propriétés distantes correspond à un type distant. De plus, la nouvelle classe distante inclut des méthodes pour effectuer des conversions avec une liste de chaînes.

TRemotableStringList = class(TRemotable)
  private
    FCaseSensitive: Boolean;
    FSorted: Boolean;
    FDuplicates: TDuplicates;
    FStrings: TStringDynArray;
  public
    procedure Assign(SourceList: TStringList);
    procedure AssignTo(DestList: TStringList);
  published
    property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive;
    property Sorted: Boolean read FSorted write FSorted;
    property Duplicates: TDuplicates read FDuplicates write FDuplicates;
    property Strings: TStringDynArray read FStrings write FStrings;
end;
class TRemotableStringList: public TRemotable
{
  private:
    bool FCaseSensitive;
    bool FSorted;
    Classes::TDuplicates FDuplicates;
    System::TStringDynArray FStrings;
  public:
    void __fastcall Assign(Classes::TStringList *SourceList);
    void __fastcall AssignTo(Classes::TStringList *DestList);
__published:
    __property bool CaseSensitive = {read=FCaseSensitive, write=FCaseSensitive};
    __property bool Sorted = {read=FSorted, write=FSorted};
    __property Classes::TDuplicates Duplicates = {read=FDuplicates, write=FDuplicates};
    __property System::TStringDynArray Strings = {read=FStrings, write=FStrings};
}

Remarquez que TRemotableStringList existe uniquement sous forme de classe de transport. Par conséquent, bien qu'elle possède une propriété Sorted (pour transporter la valeur de la propriété Sorted d'une liste de chaînes), elle n'a pas besoin de trier les chaînes qu'elle stocke mais seulement de mémoriser si les chaînes doivent être triées. Cela garantit la très grande simplicité de l'implémentation. Il vous suffit d'implémenter les méthodes Assign et AssignTo, qui effectuent des conversions avec une liste de chaînes :

procedure TRemotableStringList.Assign(SourceList: TStrings);
var I: Integer;
begin
  SetLength(Strings, SourceList.Count);
  for I := 0 to SourceList.Count - 1 do
    Strings[I] := SourceList[I];
  CaseSensitive := SourceList.CaseSensitive;
  Sorted := SourceList.Sorted;
  Duplicates := SourceList.Duplicates;
end;
procedure TRemotableStringList.AssignTo(DestList: TStrings);
var I: Integer;
begin
  DestList.Clear;
  DestList.Capacity := Length(Strings);
  DestList.CaseSensitive := CaseSensitive;
  DestList.Sorted := Sorted;
  DestList.Duplicates := Duplicates;
  for I := 0 to Length(Strings) - 1 do
    DestList.Add(Strings[I]);
end;
void __fastcall TRemotableStringList::Assign(Classes::TStringList *SourceList)
{
  SetLength(Strings, SourceList->Count);
  for (int i = 0; i < SourceList->Count; i++)
    Strings[i] = SourceList->Strings[i];
  CaseSensitive = SourceList->CaseSensitive;
  Sorted = SourceList->Sorted;
  Duplicates = SourceList->Duplicates;
}
void __fastcall TRemotableStringList::AssignTo(Classes::TStringList *DestList)
{
  DestList->Clear();
  DestList->Capacity = Length(Strings);
  DestList->CaseSensitive = CaseSensitive;
  DestList->Sorted = Sorted;
  DestList->Duplicates = Duplicates;
  for (int i = 0; i < Length(Strings); i++)
    DestList->Add(Strings[i]);
}

Vous pouvez éventuellement souhaiter recenser la nouvelle classe distante afin de pouvoir spécifier son nom de classe. Si vous ne recensez pas la classe, elle est automatiquement recensée lorsque vous recensez l'interface qui l'utilise. De manière similaire, si vous recensez la classe mais pas les types TDuplicates et TStringDynArray qu'elle utilise, ils sont automatiquement recensés. Ce code montre comment recenser la classe TRemotableStringList et le type TDuplicates. TStringDynArray est recensé automatiquement, car il s'agit d'un des types de tableaux dynamiques prédéfinis déclarés dans l'unité Types.

Ce code de recensement figure dans la section initialisation de l'unité dans laquelle vous définissez la classe distante :

RemClassRegistry.RegisterXSInfo(TypeInfo(TDuplicates), MyNameSpace, 'duplicateFlag');
RemClassRegistry.RegisterXSClass(TRemotableStringList, MyNameSpace, 'stringList', ,False);
void RegTypes()
{
  RemTypeRegistry()->RegisterXSclass(__classid(TRemotableStringList), MyNameSpace, "stringList", "", false);
}
#pragma startup initServices 32

Voir aussi