读VCL源码的第1001个问题!----- 关于PPointer(100分)

  • 主题发起人 taozhiyu
  • 开始时间
T

taozhiyu

Unregistered / Unconfirmed
GUEST, unregistred user!
type
PPointer = ^Pointer;

class function TObject.ClassInfo: Pointer;
begin
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
end;

class function TObject.ClassParent: TClass;
{$IFDEF PUREPASCAL}
begin
Pointer(Result) := PPointer(Integer(Self) + vmtParent)^;
if Result <> nil then
Pointer(Result) := PPointer(Result)^;
end;
{$ELSE}
asm
MOV EAX,[EAX].vmtParent
TEST EAX,EAX
JE @@exit
MOV EAX,[EAX]
@@exit:
end;
{$ENDIF}

function TObject.ClassType: TClass;
begin
Pointer(Result) := PPointer(Self)^;
end;

以上给出了几个定义,我不明白类似于PPointer()^和Pointer()有什么区别?有区别?没区别?
 
PPointer = ^Pointer;
PPointer是指向指针的指针。
 
请看清楚我的问题,谢谢了!
 
这是多级指针问题,也就是说:一个指针指向的内容还是一个指针。
即:
PPointer^ = APointer;
Pointer^ = AData( 但此时,也可以是一个指针,不过类型不如 PPointer 强,
系统可以检测 PPointer 的合法性,却无法检测 Pointer^ 的合法性 )
 
PPointer(Integer(Self)
Delphi 中,所有类都是指针,要声名一个类似于 void** 类型的变量,
就需用这种形式表达。
 
如果直接用 Pointer(Self)声名是失效的,
因为类本身已经是指针,无须转换,就如:
s := string(string(t))无效一样。
 
PPointer(Integer(Self) + vmtClassName)^;

Pointer(Integer(Self) + vmtClassName);
 
你看的是 D6 的代码吧,D5 不是更清晰:
class function TObject.ClassInfo: Pointer;
asm
MOV EAX,[EAX].vmtTypeInfo
end;
 
PPointer(Integer(Self) + vmtClassName)^ 检索类在 VMT 中信息(我也不大清楚)
不过,关于 VMT 好象在哪本书上看到过,是不是《Delphi 3 高级开发指南》,我忘了。

你研究这么深,想必肯定清楚 ------ 我想是
 
类型的隐式转换和返回值的关系,没有什么把?!
 
class function TObject.ClassParent: TClass
如果写成:
class function TObject.ClassParent: Pointer
那么就不用 Pointer(result) 了
 
PPointer()^與Pointer()區別在於
Pointer()只是單純把內容轉換為指針型態, 為了避免編釋器的型態檢查錯誤!
而PPointer()^, 是將內容轉換PPointer型態, 因最後再加上取值符 ^, 所以會到
所指的內存位置取回4 byte內容, 並將其視為指針型態

如 上例的
function TObject.ClassType: TClass;
begin
Pointer(Result) := PPointer(Self)^;
end;
Self 在指的是實例的內存位置, 而實例的內容置的第一個元素(4 bytes 指針)為實例
所屬的類的VMT的起始內存位置, 故以上語法可取回該實例所屬的類!

而以下:
class function TObject.ClassInfo: Pointer;
begin
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
end;
因為ClassInfo為class function, 所以在此時Self指的並不是實例內存, 而是類的VMT
起始位置, 故程式碼直接將Self位置加上徧移量後取得其中的信息

不知以上回答後, 尚有何疑問?
 
lorderic
您说得很清楚。

另外,the runtime type information (RTTI) table在哪里定义的结构?
 
接受答案了.
 
顶部