打印本文 打印本文 关闭窗口 关闭窗口
Delphi 对象模型学习笔记
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1733  更新时间:2009/4/23 18:33:59  文章录入:mintao  责任编辑:mintao
naMethod
        POP     ECX
        POP     EAX
        JE      @@Abstract
        JMP     ESI ; ESI 指向动态方法入口地址
@@Abstract:
        POP     ECX
        JMP     _AbstractError
end;
   System.GetDynaMethod 则在 DMT 中寻找该动态方法的编号,如果找到了,就从 DMT 中取得该方法的入口地址;如果找不到,则继续在父类的 DMT 中寻找该方法编号直至 TObject 的 DMT(TObject 中指向 DMT 的指针为 nil,循环到这里自然会停止):
procedure GetDynaMethod;
{       function        GetDynaMethod(vmt: TClass; selector: Smallint) : Pointer;       }
asm
        { ->    EAX     vmt of class            }
        {       SI      dynamic method index    }
        { <-    ESI pointer to routine  }
        {       ZF = 0 if found         }
        {       trashes: EAX, ECX               }

        PUSH    EDI
        XCHG    EAX,ESI
        JMP     @@haveVMT
@@outerLoop:
        MOV     ESI,[ESI]
@@haveVMT:
        MOV     EDI,[ESI].vmtDynamicTable
        TEST    EDI,EDI
        JE      @@parent
        MOVZX   ECX,word ptr [EDI]
        PUSH    ECX
        ADD     EDI,2
        REPNE   SCASW
        JE      @@found
        POP     ECX
@@parent:
        MOV     ESI,[ESI].vmtParent
        TEST    ESI,ESI
        JNE     @@outerLoop
        JMP     @@exit

@@found:
        POP     EAX
        ADD     EAX,EAX
        SUB     EAX,ECX         { this will always clear the Z-flag ! }
        MOV     ESI,[EDI+EAX*2-4]

@@exit:
        POP     EDI
end;
   这里多说一句,看 System.GetDynaMethod 的代码简直就像在欣赏一件艺术品,代码被 Borland 的工程师优化得无可挑剔,其中用到了不少技巧,你需要慢慢体会,总之好棒!
   至于象 TMyObject 中类似 WMCommand 的方法通常是由 TObject.Dispatch 来进行消息派发的,原理完全同于上面的过程,只是在 DMT 中检索的是消息 ID 而不是方法编号。具体看 TObject.Dispatch 源码及我的《Delphi 的消息机制学习笔记》。

参考文献

1. 李维.《深入核心 -- VCL架构剖析》第二章,2004.1

2. savetime."Delphi 的对象机制浅探", Jan 2004

3. 李战.《悟透delphi》之第二章 --- 《DELPHI的原子世界》

4. Ray Lischner.《Delphi in a Nutshell》,2000

上一页  [1] [2] 

打印本文 打印本文 关闭窗口 关闭窗口