如何获取保存事件处理程序的变量的地址?

例如

TExample = class(TObject)
private
    FOnChange: TNotifyEvent;
end;


我想要FOnChange私有成员,事件处理程序,变量的地址。



为什么?

我试图弄清楚谁在用垃圾覆盖我的FOnChange处理程序变量。

我正在逐步执行代码:

if Assigned(FOnChange) then
    FOnChange(Self);


从未分配任何事件处理程序,并且有一段时间在监视窗口中FOnChange变量是nil

@FOnChange: nil
Addr(FOnChange): nil


但是后来FOnChange变量变成了垃圾:

@FOnChange: $2C
Addr(FOnChange): $2C


所以我想在CPU窗口的数据窗格中观看FOnChange变量,以便可以从以下位置观看它:

00410018 00000000




00410018 0000002C


除了我不知道FOnChange的地址;我只是编了$410018

如何找到事件变量的地址?



我尝试过的事情

观察清单

OnChange: nil
@OnChange: nil
@@OnChange: Variable required
@FOnChange: nil
Assigned(OnChange): False
Assigned(FOnChange): False
@@FOnChange: $253B588
addr(addr(FOnChange)): $253B588


Alt + F5


OnChange:OnChange: TNotifyEvent $253B588
FOnChange:检查“ FOnChange”时出错:表达式错误
Self.FOnChange:检查'Self.FOnChange'时出错:表达式错误
@OnChange:@OnChange: Pointer $253B588
@@ OnChange:检查“ @@ OnChange”时出错:表达式错误
@FOnChange:@FOnChange: Pointer $253B588
@@ FOnChange:@@FOnChange: ^Untyped (no address)数据:@@ FOnChange $ 253B588`


共识似乎在地址0x253B588

但是,当我运行一些示例代码时:

MyControl1.OnChange := TheOnChangeHandler;


变成:

mov edx,[ebp+$08]         ;move stack variable $08 into edx
mov [eax+$00000208],edx   ;and then into offset $208 of my control

mov edx,[ebp+$0c]         ;move stack variable $0c into edx
mov [eax+$0000020c],edx   ;and then into offset $20c of my control


难怪我找不到FOnChange的地址,这是两个地址!

最佳答案

您可以通过Debug Inspector获取地址。要获取字段的地址,请在更改发生之前的某个时刻在代码中放置一个断点,例如,在调用构造函数之后。然后在Debug Inspector中打开对象。不确定如何以旧的IDE样式获取它,但是在D2010中,可以从“运行”->“检查...”菜单命令,“评估/修改”中的按钮或通过按键盘上的ALT-F5来获取它。 (请注意不要撞到ALT-F4!)

调试检查器将向您显示对象及其所有字段。双击其中一个字段,它将在新的“调试检查器”窗口中打开。在顶部的类似编辑框的栏中,将是您的字段的地址。您可以使用它来设置内存断点以查找值更改的位置。

09-26 18:14