在VMT结构没有太多实际知识的情况下做到这一点,并且因此在VMT结构再次改变时不太可能中断的方式是使用Rtti来实现这一点。 TRttiInstanceType
知道相关类的VmtSize
。
因此,使用VmtSize
和VMT入口是一个Pointer
function GetVirtualMethodCount(AClass: TClass): Integer;
var
AContext: TRttiContext;
AType: TRttiType;
begin
AType := AContext.GetType(AClass);
Result := (AType as TRttiInstanceType).VmtSize div SizeOf(Pointer);
end;
然而,这将包括从基类(ES)也继承所有条目。包括来自TObject
的消极抵消。但是可以从给定的基类中减去所有的条目,例如TObject
。这里是具有可变基类提供了一种方法:
function GetVirtualMethodCountMinusBase(AClass: TClass; ABaseClass: TClass): Integer;
var
AContext: TRttiContext;
AType, ABaseType: TRttiType;
begin
AType := AContext.GetType(AClass);
ABaseType := AContext.GetType(ABaseClass);
Result := ((AType as TRttiInstanceType).VmtSize - (ABaseType as TRttiInstanceType).VmtSize) div SizeOf(Pointer);
end;
而:当使用绝存在JclSysUtils
一个函数调用GetVirtualMethodCount
。虽然我不确定这是否是最新和正确的。
来源
2017-08-21 12:47:48
nil
[我在哪里可以找到有关Delphi VMT结构的信息?](https://stackoverflow.com/q/760513/576719) –
我可能会误解,但在System.Rtti中有TVirtualMethodInterceptor类。有创建的ProxyClass,这可能会帮助你,因为它创建一个VMT副本,其中的一些代码可能会帮助你。我记得有点像vmtSize。 – nil
@LURD,这个问题只是对这个问题的不正确答案,因为Stephan在他对这个答案的评论中指出:https://stackoverflow.com/a/761101/650492 – Johan