如果一直跟踪,可以看到TObject的Create方法和Destroy方法是一个空方法。那么对象是如何创建出来的呢?
原来,在编译器执行到aa:= TXXX.Create;的时候,执行了下面的几行代码:
test dl, dl
jz +$08
add esp, -$10
call @ClassCreate其中,最后一行调用了_ClassCreate函数
function _ClassCreate(AClass: TClass; Alloc: Boolean): TObject;
asm
{ -> EAX = pointer to VMT }
{ <- EAX = pointer to instance }
PUSH EDX
PUSH ECX
PUSH EBX
TEST DL,DL
JL @@noAlloc
CALL DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance
@@noAlloc:
{$IFNDEF PC_MAPPED_EXCEPTIONS}
XOR EDX,EDX
LEA ECX,[ESP+16]
MOV EBX,FS:[EDX]
MOV [ECX].TExcFrame.next,EBX
MOV [ECX].TExcFrame.hEBP,EBP
MOV [ECX].TExcFrame.desc,offset @desc
MOV [ECX].TexcFrame.ConstructedObject,EAX { trick: remember copy to instance }
MOV FS:[EDX],ECX
{$ENDIF}
POP EBX
POP ECX
POP EDX
RET{$IFNDEF PC_MAPPED_EXCEPTIONS}
@desc:
JMP _HandleAnyException { destroy the object } MOV EAX,[ESP+8+9*4]
MOV EAX,[EAX].TExcFrame.ConstructedObject
TEST EAX,EAX
JE @@skip
MOV ECX,[EAX]
MOV DL,$81
PUSH EAX
CALL DWORD PTR [ECX] + VMTOFFSET TObject.Destroy
POP EAX
CALL _ClassDestroy
@@skip:
{ reraise the exception }
CALL _RaiseAgain
{$ENDIF}
end;
在这个函数里面调用了TObject.NewInstance分配对象需要的空间
class function TObject.NewInstance: TObject;
begin
Result := InitInstance(_GetMem(InstanceSize));
end;InitInstance是为分配的空间进行初使化随后,插入下面的代码:
test dl, dl
jz +$0f
call @AfterConstruction
pop dword ptr fs:[$00000000]
add esp, $
这里调用了AfterConstruction虚拟方法,于是,一个对象就产生了。
BORLAND的工程师把这些东西都隐藏了。我查了基本资料,外带看源代码找出来。给大家分享一下!走过路过都顶一下吧
原来,在编译器执行到aa:= TXXX.Create;的时候,执行了下面的几行代码:
test dl, dl
jz +$08
add esp, -$10
call @ClassCreate其中,最后一行调用了_ClassCreate函数
function _ClassCreate(AClass: TClass; Alloc: Boolean): TObject;
asm
{ -> EAX = pointer to VMT }
{ <- EAX = pointer to instance }
PUSH EDX
PUSH ECX
PUSH EBX
TEST DL,DL
JL @@noAlloc
CALL DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance
@@noAlloc:
{$IFNDEF PC_MAPPED_EXCEPTIONS}
XOR EDX,EDX
LEA ECX,[ESP+16]
MOV EBX,FS:[EDX]
MOV [ECX].TExcFrame.next,EBX
MOV [ECX].TExcFrame.hEBP,EBP
MOV [ECX].TExcFrame.desc,offset @desc
MOV [ECX].TexcFrame.ConstructedObject,EAX { trick: remember copy to instance }
MOV FS:[EDX],ECX
{$ENDIF}
POP EBX
POP ECX
POP EDX
RET{$IFNDEF PC_MAPPED_EXCEPTIONS}
@desc:
JMP _HandleAnyException { destroy the object } MOV EAX,[ESP+8+9*4]
MOV EAX,[EAX].TExcFrame.ConstructedObject
TEST EAX,EAX
JE @@skip
MOV ECX,[EAX]
MOV DL,$81
PUSH EAX
CALL DWORD PTR [ECX] + VMTOFFSET TObject.Destroy
POP EAX
CALL _ClassDestroy
@@skip:
{ reraise the exception }
CALL _RaiseAgain
{$ENDIF}
end;
在这个函数里面调用了TObject.NewInstance分配对象需要的空间
class function TObject.NewInstance: TObject;
begin
Result := InitInstance(_GetMem(InstanceSize));
end;InitInstance是为分配的空间进行初使化随后,插入下面的代码:
test dl, dl
jz +$0f
call @AfterConstruction
pop dword ptr fs:[$00000000]
add esp, $
这里调用了AfterConstruction虚拟方法,于是,一个对象就产生了。
BORLAND的工程师把这些东西都隐藏了。我查了基本资料,外带看源代码找出来。给大家分享一下!走过路过都顶一下吧
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货