delphi - 如何获取给定类的虚拟重载过程的地址

标签 delphi

有点上下文...我需要为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/

相关文章:

java - Delphi 中通过 Java Bridge 使用 DocumentBuilderFactory 时出现段错误

delphi - TCPServer发送html到浏览器

android - 德尔福XE5安卓: how to make each listview item have its own template?

delphi - 当控件的类名非常非常长时,为什么会出现访问冲突?

multithreading - 将消息发布到之前未显示的框架后应用程序挂起

delphi - 获取作为通用参数传递的枚举大小和名称

Delphi:将 2009 升级到 XE?

Delphi Loadlibrary 返回 0 (LastErrorcde=3221225616) 这是什么意思?

delphi - 使用 Delphi 组件加密文件并使用其他实用程序解密

delphi - 对于在同一类中设置全局变量的例程,什么是好的命名约定