RTTI(四)相関関数2【転自大長者】
7888 ワード
GetOrdProp関数の詳細
SetOrdProp関数
GetEnumProp/SetEnumProp関数
GetSetProp/SetSetProp関数GetObjectProp/SetObjectProp関数
GetStrProp/SetStrProp関数
⊙GetOrdProp関数の詳細
GetOrdPropはDelphi RTTIで頻繁に使用される関数です.GetOrdPropは、オブジェクトハンドルとオブジェクト属性のTPropInfoポインタからオブジェクトの属性値を取得します.戻り値はLongintで、対応する属性タイプに強制的に変換する必要があります.
function GetOrdProp(Instance: TObject; PropInfo: PPropInfo): Longint;
GetOrdPropはTPropInfoを呼び出す.GetProc関数ポインタは、属性の戻り値を取得します.作業手順は次のとおりです.
このプロパティのタイプがclassタイプの場合、戻り値は4バイト(オブジェクトハンドル)です.
それ以外の場合はTTypeData.OrdTypeは、BLに格納される戻り値のタイプを得る.
{ TOrdType = (otSByte, otUByte, otSWord, otUWord, otSLong, otULong); }
TPropInfoをチェックします.GetProcの最初のバイト(GetProcポインタの最初のバイトであることに注意):
GetProc[0]=$FFの場合、GetProcはfield offsetであることを示す.GetProc[0]=$FEの場合、GetProcはvirtual method offsetであることを示す.GetProc[0]<$FEの場合、GetProcはstatic methodであることを示す.
その後,異なるGetProcタイプに従って解析した後,GetProcを呼び出す.BLに格納されているタイプのシンボル情報に基づいて、戻り値(EAX)のシンボル情報を修正する.BLに格納されているタイプのサイズに応じて、戻り値EAXはEAX/AX/ALです.EAX(AX/AL)は、返される属性値です.
GetOrdPropのアセンブリコードと注釈は以下の通りです.
TypInfo.pasにはGetOrdProp関数がリロードされ、PPropInfoパラメータをPropNameに置き換え、プログラマが呼び出すのを便利にします.これは、上記のGetOrdProp関数も呼び出されます.
GetOrdPropを使用する例を次に示します.
Self.Width := Self.Width - GetOrdProp(Self, 'Height');
上の文は次のようなものです.
Self.Width := Self.Width - Self.Height;
*後述のGet_Propシリーズ関数は,本関数を呼び出すか,あるいはその実現方法は本関数と類似している.
SetOrdProp関数
SetOrdProp関数はGetOrdPropの逆過程であり、TPropInfoを呼び出す.SetProc関数ポインタは、オブジェクトの属性値を設定します.SetProcポインタの最初のバイトの意味はGetProcと同様であり、このSetProcがフィールドオフセット、ダミーメソッドオフセット、および静的メソッドであることを示す.
procedure SetOrdProp(Instance: TObject; PropInfo: PPropInfo; Value: Longint);
SetOrdProcも属性名に基づいて再ロードされました.
procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
SetOrdPropのアセンブリコードはGetOrdPropとほぼ同じであるため、ここではリストされません.練習として、試してみてください.
SetOrdProp(Self, 'Height', Self.Height + 10);
この文の機能は次のとおりです.
Self.Height := Self.Height + 10;
*後述のSet_Propシリーズ関数は,本関数を呼び出すか,あるいはその実現方法は本関数と類似している.
GetEnumProp/SetEnumProp関数
GetEnumProp関数は、GetEnumNameを呼び出してGetOrdPropの戻り値を変換する列挙タイプ属性の列挙文字列を取得します.
function GetEnumProp(Instance: TObject; PropInfo: PPropInfo): string; function GetEnumProp(Instance: TObject; const PropName: string): string;
SetEnumProp関数は、列挙文字列を使用して列挙タイプ属性値を設定し、GetEnumValueを呼び出して列挙文字列を変換してからSetOrdPropを呼び出して属性値を設定します.
procedure SetEnumProp(Instance: TObject; PropInfo: PPropInfo; const Value: string); procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
GetSetProp/SetSetProp関数
GetSetProp関数は、集合型属性の文字列値を取得するために使用されます.GetOrdPropを呼び出して属性値を取得し、SetToString関数を呼び出して数値を文字列に変換します.
注意:GetOrdProp関数の戻り値はIntegerですが、256個の要素を格納できる集合タイプをどのように表していますか?答えは、publishedコレクション属性の場合、そのコレクションは最大4バイト、つまり最大32要素しか格納できません.
function GetSetProp(Instance: TObject; PropInfo: PPropInfo; Brackets: Boolean): string; function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean = False): string;
SetSetProp関数は、文字列を使用して集合タイプ属性の値を設定します.StringToSet関数を呼び出して文字列を整数値に変換し、SetOrdProp関数を使用して属性値を設定します.
procedure SetSetProp(Instance: TObject; PropInfo: PPropInfo; const Value: string); procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
試験:SetSetProp(Self,'BorderIcons','[biSystemMenu]);
GetObjectProp/SetObjectProp関数
オブジェクトは実際にはポインタ、つまり整数値なので、GetObjectPropはGetOrdPropを直接呼び出せばよい.
MinClassパラメータで指定されたObjectは、classに属する必要があります.そうでない場合はnilを返します.
function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass = nil): TObject; function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass = nil): TObject;
SetObjectPropプロパティのオブジェクトハンドルを設定します.ValidateClassパラメータは、入力されたオブジェクトタイプが属性情報のクラス情報と互換性があるかどうかを確認する必要があるかどうかを示します.
procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject; ValidateClass: Boolean = True); procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
例:
var MyFont: TFont; begin MyFont := TFont.Create; MyFont.Height := 20; SetObjectProp(Self, 'Font', MyFont); end;
GetStrProp/SetStrProp関数
GetStrProp関数は、文字列タイプの属性値を取得するために使用されます.
function GetStrProp(Instance: TObject; PropInfo: PPropInfo): string; function GetStrProp(Instance: TObject; const PropName: string): string;
Delphiは3種類の文字列をサポートしているため、GetStrPropは文字列のタイプに応じて、文字列の属性値を取得する3つの関数を呼び出します.
case PropInfo^.PropType^.Kind of tkString: GetShortStrPropAsLongStr(Instance, PropInfo, Result); tkLString: GetLongStrProp(Instance, PropInfo, Result); tkWString: GetWideStrPropAsLongStr(Instance, PropInfo, Result); end;
ここでGetShortStrPropAsLongStrはGetShortStrPropを呼び出した.GetWideStrPropAsLongStrはまたGetWideStrPropを呼び出し、文字列間のタイプ変換を行う.
SetStrProp関数は、文字列タイプの属性値を設定します.その実現方法はGetStrPropと類似している.
procedure SetStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: string); procedure SetStrProp(Instance: TObject; const PropName: string; const Value: string);
SetOrdProp関数
GetEnumProp/SetEnumProp関数
GetSetProp/SetSetProp関数GetObjectProp/SetObjectProp関数
GetStrProp/SetStrProp関数
⊙GetOrdProp関数の詳細
GetOrdPropはDelphi RTTIで頻繁に使用される関数です.GetOrdPropは、オブジェクトハンドルとオブジェクト属性のTPropInfoポインタからオブジェクトの属性値を取得します.戻り値はLongintで、対応する属性タイプに強制的に変換する必要があります.
function GetOrdProp(Instance: TObject; PropInfo: PPropInfo): Longint;
GetOrdPropはTPropInfoを呼び出す.GetProc関数ポインタは、属性の戻り値を取得します.作業手順は次のとおりです.
このプロパティのタイプがclassタイプの場合、戻り値は4バイト(オブジェクトハンドル)です.
それ以外の場合はTTypeData.OrdTypeは、BLに格納される戻り値のタイプを得る.
{ TOrdType = (otSByte, otUByte, otSWord, otUWord, otSLong, otULong); }
TPropInfoをチェックします.GetProcの最初のバイト(GetProcポインタの最初のバイトであることに注意):
GetProc[0]=$FFの場合、GetProcはfield offsetであることを示す.GetProc[0]=$FEの場合、GetProcはvirtual method offsetであることを示す.GetProc[0]<$FEの場合、GetProcはstatic methodであることを示す.
その後,異なるGetProcタイプに従って解析した後,GetProcを呼び出す.BLに格納されているタイプのシンボル情報に基づいて、戻り値(EAX)のシンボル情報を修正する.BLに格納されているタイプのサイズに応じて、戻り値EAXはEAX/AX/ALです.EAX(AX/AL)は、返される属性値です.
GetOrdPropのアセンブリコードと注釈は以下の通りです.
function GetOrdProp(Instance: TObject; PropInfo: PPropInfo): Longint;
asm
PUSH EBX
PUSH EDI
MOV EDI,[EDX].TPropInfo.PropType ; EDI <- PPTypeInfo
MOV EDI,[EDI] ; EDI <- PTypeInfo
MOV BL,otSLong ; BL <- otSLong
CMP [EDI].TTypeInfo.Kind,tkClass ; if Prop is Class
JE @@isClass ; jmp @@isClass
XOR ECX,ECX ; ECX <- 0
MOV CL,[EDI].TTypeInfo.Name.Byte[0] ; CL <- Name StrLength
MOV BL,[EDI].TTypeInfo.Name[ECX+1].TTypeData.OrdType
; BL <- Prop OrdType
@@isClass:
MOV ECX,[EDX].TPropInfo.GetProc ; ECX <- GetProc Addr
CMP [EDX].TPropInfo.GetProc.Byte[3],$FE ; cmp HiByte(GetProc), $FE
MOV EDX,[EDX].TPropInfo.Index ; EDX <- Prop Index
JB @@isStaticMethod ; if below $FE
JA @@isField ; if is $FF
{ the GetProc is a virtual method } ; if is $FE
MOVSX ECX,CX { sign extend slot offs }
ADD ECX,[EAX] { vmt + slotoffs }
CALL dword ptr [ECX] { call vmt[slot] }
JMP @@final
@@isStaticMethod:
CALL ECX ; call GetProc directly
JMP @@final
@@isField:
AND ECX,$00FFFFFF ; clear HiByte(GetProc)
ADD ECX,EAX ; ECX <- Field Addr
MOV AL,[ECX] ; AL <- Field Addr[0]
CMP BL,otSWord ; if OrdType < otSWord
JB @@final ; Exit
MOV AX,[ECX] ; else AX <- Field[0..1]
CMP BL,otSLong ; if OrdType < otSLong
JB @@final ; Exit
MOV EAX,[ECX] ; else EAX <- Field[0..3]
@@final:
CMP BL,otSLong ; if OrdType >= otSLong
JAE @@exit ; Exit
CMP BL,otSWord ; if OrdType >= otSWord
JAE @@word ; jmp @@word
CMP BL,otSByte ; if OrdType = otSByte
MOVSX EAX,AL ; AL <- Sign(EAX)
JE @@exit ; Exit
AND EAX,$FF ; clear HiWord(EAX)
JMP @@exit ; Exit
@@word:
MOVSX EAX,AX ; AX <= Sign(EAX)
JE @@exit ; if OrdType = otSWord then Exit
AND EAX,$FFFF ; clear HiWord(EAX)
@@exit:
POP EDI
POP EBX
end;
TypInfo.pasにはGetOrdProp関数がリロードされ、PPropInfoパラメータをPropNameに置き換え、プログラマが呼び出すのを便利にします.これは、上記のGetOrdProp関数も呼び出されます.
function GetOrdProp(Instance: TObject; const PropName: string): Longint;
begin
Result := GetOrdProp(Instance, FindPropInfo(Instance, PropName));
end;
GetOrdPropを使用する例を次に示します.
Self.Width := Self.Width - GetOrdProp(Self, 'Height');
上の文は次のようなものです.
Self.Width := Self.Width - Self.Height;
*後述のGet_Propシリーズ関数は,本関数を呼び出すか,あるいはその実現方法は本関数と類似している.
SetOrdProp関数
SetOrdProp関数はGetOrdPropの逆過程であり、TPropInfoを呼び出す.SetProc関数ポインタは、オブジェクトの属性値を設定します.SetProcポインタの最初のバイトの意味はGetProcと同様であり、このSetProcがフィールドオフセット、ダミーメソッドオフセット、および静的メソッドであることを示す.
procedure SetOrdProp(Instance: TObject; PropInfo: PPropInfo; Value: Longint);
SetOrdProcも属性名に基づいて再ロードされました.
procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
SetOrdPropのアセンブリコードはGetOrdPropとほぼ同じであるため、ここではリストされません.練習として、試してみてください.
SetOrdProp(Self, 'Height', Self.Height + 10);
この文の機能は次のとおりです.
Self.Height := Self.Height + 10;
*後述のSet_Propシリーズ関数は,本関数を呼び出すか,あるいはその実現方法は本関数と類似している.
GetEnumProp/SetEnumProp関数
GetEnumProp関数は、GetEnumNameを呼び出してGetOrdPropの戻り値を変換する列挙タイプ属性の列挙文字列を取得します.
function GetEnumProp(Instance: TObject; PropInfo: PPropInfo): string; function GetEnumProp(Instance: TObject; const PropName: string): string;
SetEnumProp関数は、列挙文字列を使用して列挙タイプ属性値を設定し、GetEnumValueを呼び出して列挙文字列を変換してからSetOrdPropを呼び出して属性値を設定します.
procedure SetEnumProp(Instance: TObject; PropInfo: PPropInfo; const Value: string); procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
GetSetProp/SetSetProp関数
GetSetProp関数は、集合型属性の文字列値を取得するために使用されます.GetOrdPropを呼び出して属性値を取得し、SetToString関数を呼び出して数値を文字列に変換します.
注意:GetOrdProp関数の戻り値はIntegerですが、256個の要素を格納できる集合タイプをどのように表していますか?答えは、publishedコレクション属性の場合、そのコレクションは最大4バイト、つまり最大32要素しか格納できません.
function GetSetProp(Instance: TObject; PropInfo: PPropInfo; Brackets: Boolean): string; function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean = False): string;
SetSetProp関数は、文字列を使用して集合タイプ属性の値を設定します.StringToSet関数を呼び出して文字列を整数値に変換し、SetOrdProp関数を使用して属性値を設定します.
procedure SetSetProp(Instance: TObject; PropInfo: PPropInfo; const Value: string); procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
試験:SetSetProp(Self,'BorderIcons','[biSystemMenu]);
GetObjectProp/SetObjectProp関数
オブジェクトは実際にはポインタ、つまり整数値なので、GetObjectPropはGetOrdPropを直接呼び出せばよい.
MinClassパラメータで指定されたObjectは、classに属する必要があります.そうでない場合はnilを返します.
function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass = nil): TObject; function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass = nil): TObject;
SetObjectPropプロパティのオブジェクトハンドルを設定します.ValidateClassパラメータは、入力されたオブジェクトタイプが属性情報のクラス情報と互換性があるかどうかを確認する必要があるかどうかを示します.
procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject; ValidateClass: Boolean = True); procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
例:
var MyFont: TFont; begin MyFont := TFont.Create; MyFont.Height := 20; SetObjectProp(Self, 'Font', MyFont); end;
GetStrProp/SetStrProp関数
GetStrProp関数は、文字列タイプの属性値を取得するために使用されます.
function GetStrProp(Instance: TObject; PropInfo: PPropInfo): string; function GetStrProp(Instance: TObject; const PropName: string): string;
Delphiは3種類の文字列をサポートしているため、GetStrPropは文字列のタイプに応じて、文字列の属性値を取得する3つの関数を呼び出します.
case PropInfo^.PropType^.Kind of tkString: GetShortStrPropAsLongStr(Instance, PropInfo, Result); tkLString: GetLongStrProp(Instance, PropInfo, Result); tkWString: GetWideStrPropAsLongStr(Instance, PropInfo, Result); end;
ここでGetShortStrPropAsLongStrはGetShortStrPropを呼び出した.GetWideStrPropAsLongStrはまたGetWideStrPropを呼び出し、文字列間のタイプ変換を行う.
SetStrProp関数は、文字列タイプの属性値を設定します.その実現方法はGetStrPropと類似している.
procedure SetStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: string); procedure SetStrProp(Instance: TObject; const PropName: string; const Value: string);