Delphi RTTI从记录中获取值

时间:2017-01-27 08:28:42

标签: delphi rtti codesite

寻求从记录到CodeSite获取值的帮助。虽然我有基本值(int,string ..)的记录,但一切都有效。

但问题来自于记录中的阵列。

姓:WideChar的数组[0..35]
名称:WideChar的数组[0..25]

(我找到了这个,但有什么办法吗?)
Getting type of record field with RTTI fails for static arrays

虽然我想获取Surname / Name的字段值,但TRttiField.FieldType.TypeKind为null。

任何人都知道如何将属性的值转换为字符串?

有我的程序。

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;

有第二个从字段中获取价值的程序

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;

0 个答案:

没有答案