RAD Studio |  |

Remotable Object Example
See Also
Collapse All

This example shows how to create a remotable object for a parameter on an invokable interface where you would otherwise use an existing class. In this example, the existing class is a string list (TStringList). To keep the example small, it does not reproduce the Objects property of the string list.

Because the new class is not scalar, it descends from TRemotable rather than TRemotableXS. It includes a published property for every property of the string list you want to communicate between the client and server. Each of these remotable properties corresponds to a remotable type. In addition, the new remotable class includes methods to convert to and from a string list.

Copy Code

    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;

Copy Code

    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};
    }

Note that TRemotableStringList exists only as a transport class. Thus, although it has a Sorted property (to transport the value of a string list's Sorted property), it does not need to sort the strings it stores, it only needs to record whether the strings should be sorted. This keeps the implementation very simple. You only need to implement the Assign and AssignTo methods, which convert to and from a string list:

Copy Code

    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;

Copy Code

    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]);
    }

Optionally, you may want to register the new remotable class so that you can specify its class name. If you do not register the class, it is registered automatically when you register the interface that uses it. Similarly, if you register the class but not the TDuplicates and TStringDynArray types that it uses, they are registered automatically. This code shows how to register the TRemotableStringList class and the TDuplicates type. TStringDynArray is registered automatically because it is one of the built-in dynamic array types declared in the Types unit.

This registration code goes in the initialization section of the unit where you define the remotable class:

Copy Code

    RemClassRegistry.RegisterXSInfo(TypeInfo(TDuplicates), MyNameSpace, 'duplicateFlag');
    RemClassRegistry.RegisterXSClass(TRemotableStringList, MyNameSpace, 'stringList', '',False);

Copy Code

    void RegTypes()
    {
      RemTypeRegistry()->RegisterXSclass(__classid(TRemotableStringList), MyNameSpace, "stringList", "", false);
    }
    #pragma startup initServices 32

See Also

Registering Nonscalar Types

Using Remotable Objects

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!