pyscripter 689 Posted May 3, 2020 I was looking at an old blog post by Barry Kelly. In particular the function: function TLocation.FieldRef(const name: string): TLocation; var f: TRttiField; begin if FType is TRttiRecordType then begin f := FType.GetField(name); Result.FLocation := PByte(FLocation) + f.Offset; Result.FType := f.FieldType; end else if FType is TRttiInstanceType then begin f := FType.GetField(name); Result.FLocation := PPByte(FLocation)^ + f.Offset; Result.FType := f.FieldType; end else raise Exception.CreateFmt('Field reference applied to type %s, which is not a record or class', [FType.Name]); end; I am puzzled by the line: Result.FLocation := PPByte(FLocation)^ + f.Offset; If Flocation is an object (FType is TRttiInstance type) and I am having a record field inside the object, the Result.FLocation should be PByte(FLocation) + f.offset, i.e. the same as for FType is TRttiRecord. Barry Kelly is probably the guy that wrote the Rtti stuff, so he knows what he is talking about. What I am missing? Share this post Link to post
Attila Kovacs 629 Posted May 3, 2020 it's in the comments Quote The code is different between instances and records because instances need a dereference before adding the offset. It could be written differently, of course. 1 Share this post Link to post
pyscripter 689 Posted May 3, 2020 (edited) @Attila Kovacs Thanks I missed that. Now I get it. The key is in class function TLocation.FromValue(C: TRttiContext; const AValue: TValue): TLocation; begin Result.FType := C.GetType(AValue.TypeInfo); Result.FLocation := AValue.GetReferenceToRawData; end; If AValue contains an object, Flocation would a pointer to a pointer. That was not the case in my testing. He could do the dereferencing in this function of course. Edited May 3, 2020 by pyscripter Share this post Link to post