如何获取保存事件处理程序的变量的地址?
例如
TExample = class(TObject)
private
FOnChange: TNotifyEvent;
end;
我想要FOnChange
私有(private)成员、事件处理程序、变量的地址。
为什么?
我正在尝试找出是谁用垃圾覆盖了我的 FOnChange
处理程序变量。
我正在单步执行代码:
if Assigned(FOnChange) then
FOnChange(Self);
没有分配任何事件处理程序,并且有一段时间观察窗口中的FOnChange
变量为nil
:
@FOnChange: nil
Addr(FOnChange): nil
但后来 FOnChange
变量变成了垃圾:
@FOnChange: $2C
Addr(FOnChange): $2C
所以我想在CPU窗口的数据 Pane 中观察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:指针 $253B588
- @@OnChange:检查“@@OnChange”时出错:表达式错误
- @FOnChange:
@FOnChange:指针 $253B588
- @@FOnChange:
@@FOnChange:^未键入(无地址)
数据: @@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
的地址,这是两个地址!
最佳答案
您可以通过调试检查器获取该地址。要获取字段的地址,请在更改发生之前的某个时刻在代码中放置一个断点,例如在调用构造函数之后。然后在调试检查器中打开您的对象。不知道如何在旧的 IDE 风格中获得它,但在 D2010 中,您可以通过“运行”->“检查...”菜单命令、“评估/修改”中的按钮或通过按键盘上的 ALT-F5 来获得它。 (小心不要按 ALT-F4!)
调试检查器将向您显示对象及其所有字段。双击其中一个字段,它将在新的调试检查器窗口中打开。在顶部类似编辑框的栏中将显示您的字段的地址。您可以使用它来设置内存断点以查找值发生变化的位置。
关于Delphi:如何获取事件变量的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3086623/