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.
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}; }
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:
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]); }
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:
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
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
|
What do you think about this topic? Send feedback!
|