delphi中as,is关键字是如何工作的?(50分)

  • 主题发起人 乐乐0898
  • 开始时间

乐乐0898

Unregistered / Unconfirmed
GUEST, unregistred user!

我的问题是delphi中as,is关键字是如何工作的?特别是as,它可以把一个类转换成另一个类我从delphi中的system.pas中截取as关键字代码请求给与讲解,再次感谢!!
我的E-Mail地址 yueyue0898@sina.com
procedure _AsClass
asm
{_> EAX left operand(class)
{ EDX VMT of right operand
{<_ EAX if left is derived from right ,else runtime
error }
TEST EAX,EAX
JE @@exit
MOV ECX,EAX
@@loop
MOV ECX,[ECX]
CMP ECX,EDX
JE @@exit
MOV ECX,[ECX].vmtParent
TEST ECX,ECX
JNE @@loop
{ do runtime error}
MOV AL,reInvalidCast
JMP error
@@exit:
end;
 
as 操作实际上就是调用_IntfCast函数而已,直接看源码好了
procedure _IntfCast(var Dest: IInterface
const Source: IInterface
const IID: TGUID);
{$IFDEF PUREPASCAL}
// PIC: EBX must be correct before calling QueryInterface
begin
if Source = nil then
Dest := nil
else if Source.QueryInterface(IID, Dest) <> 0 then
Error(reIntfCastError);
end;
{$ELSE}
asm
TEST EDX,EDX
JE _IntfClear
PUSH EAX
PUSH ECX
PUSH EDX
MOV ECX,[EAX]
TEST ECX,ECX
JE @@1
PUSH ECX
MOV EAX,[ECX]
CALL DWORD PTR [EAX] + VMTOFFSET IInterface._Release
MOV EDX,[ESP]
@@1: MOV EAX,[EDX]
CALL DWORD PTR [EAX] + VMTOFFSET IInterface.QueryInterface
TEST EAX,EAX
JE @@2
MOV AL,reIntfCastError
JMP Error
@@2:
end;
{$ENDIF}
 

TEST EAX,EAX //是当前类的类型
JE @@exit //是就退出
MOV ECX,EAX //否则把需要转换的类型信息指针给了ecx
@@loop
MOV ECX,[ECX] //取内容到ecx
CMP ECX,EDX //指针是需要转换的类
JE @@exit //是就退出
MOV ECX,[ECX].vmtParent//不是,就找父类的类型信息指针
TEST ECX,ECX//比较
JNE @@loop//还不是就循环
{ do runtime error}
MOV AL,reInvalidCast//一直找完还没有找到
JMP error//报错
@@exit:
end;
原理:
主要是RTTI,你可以在品雪的网站上找到DELPHI对象内存模型,或者看system单元,
时间来不及了,你详细看一下他们的资料
 
谢谢各位对我的支持,可我还是不太明白,对象在delphi中表现为指针,as转换是把一个对象的指针
给另一个对象的指针吗?
 
顶部