5

looking for help with getting values from record to CodeSite. While i have record with basic values (int, string..) everything works okey.

But problem comes with arrays in record.

Surname : array[0..35] of WideChar
Name : array[0..25] of WideChar

(I have found this but is there any way? )
Getting type of record field with RTTI fails for static arrays

While i want to get field value of Surname / Name the TRttiField.FieldType.TypeKind is null.

Anybody knows any way how to get values of the property to string?

There is my procedure.

class procedure TCodeSite.SendObject<T>(Category: String; lObject : T; Msg: String);
var
lRTTIContext : TRttiContext;
lRTTIObjectType : TRttiType;
lRTTIField : TRttiField;
lRTTIRecordInRecord : TRttiRecordType;
lRTTIFieldInRecord : TRttiField;
lRTTIPointerType : TRttiPointerType;
lRTTIPointerValue : TValue;
lFieldName : string;
lFieldNameInRecord : string;
lStringList : TStringList;
begin
  {$IfNDef CodeSiteDisabled}
    if isActiveDebugCategory(Category) then
begin
  lStringList := TStringList.Create;
  lRTTIContext := TRttiContext.Create;
  lRTTIObjectType := lRTTIContext.GetType(TypeInfo(T));

  if lRTTIObjectType.TypeKind = tkRecord then
  begin
    for lRTTIField in lRTTIObjectType.GetFields do
    begin

      lFieldName := ParseFieldName(lRTTIField.ToString);

      case lRTTIField.FieldType.TypeKind of
        tkRecord:
          begin
            lRTTIRecordInRecord := lRTTIField.FieldType.AsRecord;
            lStringList.Add(lFieldName);
            for lRTTIFieldInRecord in lRTTIRecordInRecord.GetFields do
            begin
               lFieldNameInRecord := ParseFieldName(lRTTIFieldInRecord.ToString);
               lStringList.Add('    '+lFieldNameInRecord +' '+GetFieldValue<T>(Addr(lObject), lRTTIFieldInRecord));
            end;
          end;
        tkPointer:
          begin
            lRTTIPointerType := lRTTIField.FieldType as TRttiPointerType;

            if lRTTIPointerType.ReferredType.TypeKind = tkRecord then
            begin
              lRTTIPointerValue := lRTTIField.GetValue(Addr(lObject));
              if (not lRTTIPointerValue.IsEmpty) then
              begin
                for lRTTIFieldInRecord in lRTTIPointerType.ReferredType.GetFields do
                begin
                    lStringList.Add(lFieldName + GetFieldValue<T>(Addr(lObject), lRTTIFieldInRecord));
                end;
              end;
            end;
          end
            else lStringList.Add(lFieldName + ' ' + GetFieldValue<T>(Addr(lObject), lRTTIField));
      end;
    end;

    CodeSite.Category := Category;
    CodeSite.Send(Msg, lStringList);
  end;
  lRTTIContext.Free;
end;
  {$EndIf}
end;

There is Second procedure to get value from field

class function TCodeSite.GetFieldValue<T>(const pipInstance : Pointer;
                               const piclField : TRttiField) : string;
begin
  if not (Assigned(piclField.FieldType))  then
   begin
    Result := 'Pica';
     Exit;
  end;

case piclField.FieldType.TypeKind of
  tkEnumeration : Result := BoolToStr(piclField.GetValue(pipInstance).AsBoolean);
  tkFloat: Result := FloatToStr(piclField.GetValue(pipInstance).AsExtended);
  tkInt64: Result := IntToStr(piclField.GetValue(pipInstance).AsInt64);
  tkInteger: Result := IntToStr(piclField.GetValue(pipInstance).AsInteger);
  tkString,tkUString: Result := Trim(piclField.GetValue(pipInstance).AsString);
end;
 end;
Community
  • 1
  • 1
  • See also [Convert Record to Serialized Form Data for sending via HTTP](http://stackoverflow.com/a/11514088/576719). I think you need to make the index declared as a range as well, besides declaring the type of the array. – LU RD Jan 27 '17 at 09:03

0 Answers0