System.pas文件包含有关硬编码VMT偏移量的大量信息,但实际上似乎并未真正说明VMT本身的结构。我真正想知道的是,有没有办法在运行时找出VMT的大小,或者换句话说,给定类有多少虚拟方法?
答案 0 :(得分:13)
你想知道VMT结构怎么样?您还知道它是一个内部实现细节,可能会发生变化(并且随着时间的推移而发生变化)。
要回答您的具体问题,以下是查找给定类的虚拟方法数量的简单方法:
function GetVirtualMethodCount(AClass: TClass): Integer;
begin
Result := (PInteger(Integer(AClass) + vmtClassName)^ -
(Integer(AClass) + vmtParent) - SizeOf(Pointer)) div SizeOf(Pointer);
end;
这是有效的,因为我碰巧知道表示类名的字符串紧跟在VMT中的所有虚拟方法向量之后。
我也知道在所有与VMT指针本身负偏移的TObject上有11个虚拟方法(对于D2009,对于D2007和之前为9)。
这就是vmtParent引用的原因。
最后,通过使用TClass类引用,您可以将任何TObject派生类传递给此函数并获取虚拟方法的数量。
答案 1 :(得分:9)
我很确定Hallvard在VMT上有所作为。果然,他有Hack #8: Explicit VMT calls引用了Ray Lischner 秘密的Delphi 2 和 Delphi in a Nutshell 。
这是他被黑客入侵的VMT版本
type
PClass = ^TClass;
PSafeCallException = function (Self: TObject; ExceptObject:
TObject; ExceptAddr: Pointer): HResult;
PAfterConstruction = procedure (Self: TObject);
PBeforeDestruction = procedure (Self: TObject);
PDispatch = procedure (Self: TObject; var Message);
PDefaultHandler = procedure (Self: TObject; var Message);
PNewInstance = function (Self: TClass) : TObject;
PFreeInstance = procedure (Self: TObject);
PDestroy = procedure (Self: TObject; OuterMost: ShortInt);
PVmt = ^TVmt;
TVmt = packed record
SelfPtr : TClass;
IntfTable : Pointer;
AutoTable : Pointer;
InitTable : Pointer;
TypeInfo : Pointer;
FieldTable : Pointer;
MethodTable : Pointer;
DynamicTable : Pointer;
ClassName : PShortString;
InstanceSize : PLongint;
Parent : PClass;
SafeCallException : PSafeCallException;
AfterConstruction : PAfterConstruction;
BeforeDestruction : PBeforeDestruction;
Dispatch : PDispatch;
DefaultHandler : PDefaultHandler;
NewInstance : PNewInstance;
FreeInstance : PFreeInstance;
Destroy : PDestroy;
{UserDefinedVirtuals: array[0..999] of procedure;}
end;
你需要阅读他的文章,了解有关黑客的更多信息。
答案 2 :(得分:2)
谷歌搜索:-P为“delphi vmt”产生this。也许这会给你一个开始。
答案 3 :(得分:2)
我将插入我自己的网站:
What is the virtual-method table?
我认为,就像Delphi 2005一样准确。
VMT没有任何值给出它所拥有的虚方法指针的数量。除了编译器之外什么都不需要知道这些信息,所以没有理由记录它以便在运行时使用。
答案 4 :(得分:0)
我记得有一些关于delphi vmt的信息,请参阅“delphi简介”一书。 你可以从delphi in a nutshell chapter 2或this
开始