有点上下文...我需要为a bug in the VCL's TField.CopyData routine写一个修复程序。
我不是忠实于重新编译VCL的忠实拥护者,所以我通常选择method hooks。
通常,这非常简单,编写替换方法并将其挂接到原始方法上:
HookProc(@TMenu.ProcessMenuChar, @TPatchMenu.ProcessMenuChar, Backup);
但是这一次,该方法是虚拟的并且重载。我似乎找不到可靠的方法来获取正确的方法地址。
如果没有重载,我可以简单地使用
@TField.CopyData
,它将起作用,但是不能保证为重载的函数提供正确的地址。如果不是虚拟的,我可以扩展the method described here并执行以下操作
type
TCopyDataMethod = procedure(Source, Dest : TValueBuffer) of object;
procedure DoHook;
var vOldMethod : TCopyDataMethod;
begin
vOldMethod := TField(nil).CopyData;
HookProc(TMethod(vOldMethod).Code, @TSomeClass.NewMethod, Backup);
end;
但这会导致访问冲突(它使用nil引用在VMT中查找正确的CopyData地址)。
我尝试了各种语法,这些语法在编译时都给了我“不兼容的类型”。
我确实想出了一个解决方案(作为答案发布),但这并不理想。
最佳答案
从大卫·赫弗南(David Heffernan)的答案中得到启发,这就是我一直在寻找/希望得到的解决方案。
type
TCopyDataMethod = procedure(Source, Dest : TValueBuffer) of object;
procedure Proc;
var VMT : NativeInt;
vMethod : TCopyDataMethod;
begin
VMT := NativeInt(TField);
vMethod := TField(@Vmt).CopyData;
uOriginalAddress := @vMethod;
[...]
end;
我相信这是尽可能简单的方法。
关于delphi - 如何获取给定类的虚拟重载过程的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34617237/