0

We're seeing an issue with Delphi XE where, at times, TRttiType.GetTypes returns an empty array. Other times, using the exact same code, the array contains the expected types. The error is occurring when marshalling/unmarshalling classes over DataSnap using TJSONMarshal and TJSONUnMarshal.

Any idea why the call to GetTypes in the unit below would return an empty array? (The $M directive should not be required. It is there as I've tried several brute-force approaches, including $STRONGLINKTYPES.)

unit uTest;

interface

uses
  Classes;

type
{$M+}
  TMyClass = class(TPersistent)
  public
    Value1 : Integer;
    Value2 : String;
    Value3 : Currency;
    Value4 : Boolean;
    Value5 : Double;
end;

procedure Test;

implementation

uses
  Dialogs, Rtti, SysUtils;

procedure Test;
var
  c: TRttiContext;
  t: TRttiType;
  a: TArray<TRttiField>;

begin
  c := TRttiContext.Create;
  t := c.GetType(TypeInfo(TMyClass));
  if Assigned(t) then begin
    a := t.GetFields;
    ShowMessage(IntToStr(High(a)));
  end
  else
    ShowMessage('TMyClass not found');
end;

procedure ForceReferenceToClass(C: TClass);
var
  dummy: TObject;
begin
  dummy := C.Create();
  dummy.Free();
end;

initialization
  ForceReferenceToClass(TMyClass);
end.

Thanks

Dalija Prasnikar
  • 27,212
  • 44
  • 82
  • 159
Jon Robertson
  • 591
  • 6
  • 18
  • Where is the issue ? On `GetType`or on `GetFields` function ? – TridenT Mar 30 '15 at 18:53
  • There is a problem with json, #QC#81869, QC#81862 and QC#82857. I think there are more. I'll see if I can find them. – LU RD Mar 31 '15 at 16:04
  • 1
    Here it is: [TRTTIContext multi-thread issue](http://stackoverflow.com/a/27373857/576719). RTTI is not thread safe, See [RSP-9815 TRealPackage.FindType thread unsafe](https://quality.embarcadero.com/browse/RSP-9815). This will have implications on DataSnap/JSON etc. Also in Delphi-XE. – LU RD Mar 31 '15 at 16:22
  • 1
    More, [TJson.JsonToObject throws errors in a multi-thread enviroment](http://stackoverflow.com/q/28341308/576719). – LU RD Mar 31 '15 at 16:37
  • 1
    Or maybe this is helpful, [Delphi XE2 RTTI broken?](http://stackoverflow.com/a/12687747/576719). – LU RD Mar 31 '15 at 16:49
  • 1
    ForceReferenceToClass is very very badly implemented. It should do absolutely nothing. – David Heffernan Mar 31 '15 at 19:47
  • 1
    You can also delete `c := TRttiContext.Create;` which is needless. Better to use a single global context. The designers at Emba really screwed the design up here. – David Heffernan Mar 31 '15 at 19:49
  • David: I shouldn't have included the code that is in ForceReferenceToClass. It was added to my test project during troubleshooting to make absolutely sure the class was linked into the EXE. The TRttiContext.Create usage was taken from several examples I found online, including StackOverflow. I have experience using the old TypInfo RTTI but very little experience using the new RTTI implementation. Thanks for your comments. – Jon Robertson Apr 01 '15 at 20:20
  • LU RD: I'll look into those issues. We're on XE, so any issues introduced in XE2 aren't a factor. We are marshalling an object between a DataSnap server and client, so if either TRTTIContext or Delphi's JSON implementation is not thread safe, that's a serious issue. Also quite surprising, since all method calls in a DataSnap server use JSON to pass and return parameter values. – Jon Robertson Apr 01 '15 at 20:23
  • LU RD: GetType returns the correct type. GetFields returns an empty array, even though there are public fields in the class. – Jon Robertson Apr 01 '15 at 20:26
  • Does this answer your question? [TJson.JsonToObject throws errors in a multi-thread environment](https://stackoverflow.com/questions/28341308/tjson-jsontoobjectt-throws-errors-in-a-multi-thread-environment) – Dalija Prasnikar May 03 '21 at 09:51

0 Answers0