2014-11-09 7 views
2

RttiHelper 클래스를 코딩했습니다. 특히 클래스의 모든 필드 이름을 검색 할 수 있습니다. 이 절차는 필드가 개체 또는 배열인지 여부를 성공적으로 결정하지만 필드가 레코드인지 여부를 확인할 수 없습니다.클래스의 필드가 레코드 인 경우 Rtti를 사용하여 결정하는 방법

unit Form1 
interface 
uses RttiHelper; 
type 
    tMyRec = Record 
    ... 
    end;  
... 
implementation 
var MyRec : tMyRec; 
procedure FormCreate (Sender: tObject); 
begin 
    SetRec (@MyRec); 
end; 

unit RttiHelper 
interface 
type 
    tObjRec = class 
    Rec : Pointer; 
    end; 
    ... 
    tRttiHelperClass = class (tObject) 
    private 
    fObjRec: tObjRec; 
    ... 
    procedure GetFieldsNames; 
    ... 
    public 
    ... 
    procedure SetRec (aRec: Pointer); 
    ... 
    published 
    ... 
    constructor Create (aOwner: tComponent); 
    ... 
    end; 
implementation 
constructor tRttiHelperClass.Create (aOwner: tComponent); 
begin 
    fCtxt := tRttiContext.Create; 
end; 
procedure tRttiHelperClass.SetRec (aRec: Pointer); 
begin 
    private 
    fObjectRec.Rec := aRec; 
    procedure GetFieldsNames; 
end; 
procedure tRttiHelperClass.GetFieldsNames; 
var f  : Word ; 
    fields : tRttiType; 
begin 
    with fRttiContext do begin 
     RttiType := GetType (fObjRec.ClassType); 
     Fields := RttiType.GetFields; 
     for f := Low (fields) to High (fields) fo begin 
      if fields[f].GetValue (tObject (fObjRec^)).IsArray then // this works 
       ... 
      if fields[f].GetValue (tObject (fObjRec^)).IsObject then // this works 
       ... 
      if fields[f].GetValue (tObject (fObjRec^)).IsRecord then // "undeclared identifier IsRecord" 
       ... 
    end; 
end; 
end. 

내가 기록 작업을하기 위해, 내가 tRttiRecordType를 사용해야 않는다는 것을 알고 있지만, 내가이 작업을 수행하는 올바른 방법을 찾을 수 없습니다 : 코드를 따릅니다. 일부 필드가 레코드인지 확인하는 올바른 코드는 무엇입니까? 감사합니다. .

답변

2

이 대신보십시오 : System.Rtti.TRttiField.FieldTypeSystem.Rtti.TRttiType.IsRecord에서

if fields[f].FieldType.IsRecord then 

.


여기에 근원적 인 문제는 형식화되지 않은 포인터에서 레코드 필드를 해결할 수 없다는 것입니다. 그런 식으로하기 위해서, 당신의 기록을 TValue로 전달하십시오.

procedure SetRec(aRec: TValue); 

전화를 이런 식으로 이렇게하고 기록의 내용을 해결하는 방법보다 완벽한 자습서

SetRec(TValue.From(MyRec)); 

Convert Record to Serialized Form Data for sending via HTTP를 참조하십시오.

TValue 전달은 클래스 및 기타 유형에서도 작동합니다.

+0

나는 그것들을 시도했지만, 필드 [f]는 실제로 포인터가 되었기 때문에'tkPointer'를 반환합니다. 필드 [f]가 가리키는 기록을 확인하는 방법이 있어야합니다. – user2383818

+0

Ahh가 질문을 잘못 읽었습니다. 이런 식으로 레코드에 사용할 수있는 RTTI는 없습니다. 레코드 유형을 도우미에게 전달해야합니다. –