Frage

Wie erhalte ich die Adresse der Variablen einen Event-Handler halten?

z.

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

Ich mag die Adresse der FOnChange privaten Member, Event-Handler, variabel ist.


Warum?

Ich versuche, herauszufinden, wer meine FOnChange Handler Variable mit Junk wird überschrieben wird.

i durch Code verlasse:

if Assigned(FOnChange) then
    FOnChange(Self);

Keine Event-Handler immer zugeordnet ist, und für ein, während die FOnChange Variable nil im Ansichtsfenster:

@FOnChange: nil
Addr(FOnChange): nil

Aber später die FOnChange Variable wird immer in Junk gedreht:

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

Also ich mag die FOnChange Variable in Datenbereich des CPU-Fensters sehen, dass so kann ich es sehen, um aus:

00410018 00000000

00410018 0000002C

Außer, dass ich dies nicht tun weiß die Adresse des FOnChange; i aus nur die $410018.

Wie kann ich die Adresse finden ein Ereignis Variable?


Dinge, die ich habe versucht,

Merkliste

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: Fehler Inspektion 'FOnChange': Ausdruck Fehler
  • Self.FOnChange: Fehler Inspektion 'Self.FOnChange': Ausdruck Fehler
  • @OnChange : @OnChange: Pointer $253B588
  • @@ OnChange : Fehler Untersuchungs '@@ OnChange': Ausdruck Fehler
  • @FOnChange : @FOnChange: Pointer $253B588
  • @@ FOnChange : @@FOnChange: ^Untyped (no address) Daten: @@ FOnChange $ 253B588`

Die Konsensus scheint Adresse 0x253B588 zu sein.

Doch wenn ich laufen einige Beispiel-Code:

MyControl1.OnChange := TheOnChangeHandler;

Dass verwandelt sich in:

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

Kein Wunder, dass ich nicht eine Adresse FOnChange finden kann, ist es zwei Adressen!

War es hilfreich?

Lösung

Sie können die Adresse durch den Debug-Inspektoren erhalten. Um die Adresse eines Feldes zu erhalten, setzen Sie irgendwann einen Haltepunkt in Ihrem Code, bevor die Änderung geschehen ist, beispielsweise direkt nach den Konstruktor aufrufen. Dann öffnen Sie Ihr Objekt in dem Debug-Inspektoren. Nicht sicher, wie Sie es in dem alten IDE-Stil, aber in D2010 können Sie dies aus der Run- bekommen> Inspizieren ... Menübefehl von einer Schaltfläche in Auswerten / Ändern oder durch Schlagen ALT-F5 auf der Tastatur. (Seien Sie vorsichtig, Sie nicht ALT-F4 getroffen!)

Der Debug-Inspektor zeigt Ihnen Ihr Objekt mit allen seinen Feldern. Doppelklicken Sie auf eines der Felder und es wird in einem neuen Debug-Inspektor-Fenster. In dem Bearbeitungsfeld artigen Leiste am oberen Rand wird die Adresse des Feldes sein. Damit können Sie einen Speicherhaltepunkt gesetzt werden, wo die Wertänderungen zu finden.

Andere Tipps

Nicht sicher in Delphi 5, aber Sie sollten ein Data- Breakpoint- (oder eine Adresshaltepunkt) auf Ihrem AExample.FOnChange setzen können.
Es würde brechen, wenn die Wertänderungen.

Da Sie nicht die intelligente Lösung von François vorgeschlagen verwenden können, ist es Zeit Hacking zu bekommen! Irgendwo, an jedem Ort können Sie einen brakepoint setzen, schreiben Code wie folgt:

var X:TExample;
X.OnChange := nil;

Setzen Sie ein brakepoint auf dem X.OnChange: = nil Linie; Wenn der Debugger hält dort an, einen Blick auf die Demontage Scheibe nehmen, werden Sie etwas sehen:

; assembler blah blah to get the address of X
xor EDX ; or whatever the compiler finds appropriate this time of day
mov [eax + $00000288], edx
mov [eax + $0000028c], edx

Sie kümmern sich nicht um die Register durch den Compiler verwendet, kümmern Sie über die $ 288, der Offset für den ersten MOV-Befehl verwendet. Das ist der Versatz von der „X“ Adresse zum FOnChange Feld. Beachten Sie es nach unten. Nun zu Ihren Buggy Programm zurückgehen, stellen eine brakepoint irgendwo, drücken Sie Alt + F5, um die Debug-Inspektor aufzurufen (gefolgt von Strg + N, wenn Sie nicht mit einem leeren Eingabefeld präsentiert Ihre Abfrage in eingeben) und write „Integer ( MyExampleVariable) "; Was auch immer Sie erhalten, addieren Sie die Nummer, die Sie im vorherigen Schritt notiert und Sie haben die Adresse des FOnChange für die MyExampleVariable Instanz eingereicht, können Sie jetzt eine Adresse brakepoint gesetzt.

Ich weiß nicht, ob sie in Delphi 5 vorhanden ist, aber die Art TMethod und die Funktion Method sollte hilfreich sein.

  

Warum?

     

Ich versuche, herauszufinden, wer meinen FOnChange Handler Variable mit Junk wird überschrieben wird.

kann ich das bisschen beantworten - Sie sind! Oder Sie suchen an der falschen Instanz, die nicht korrekt erstellt wird? nicht korrekt verwiesen wird? Es wird so etwas sein. Der Delphi-Debugger ist gut ein Ding zu machen, die nicht aussehen existiert, wie es der Fall ist, bis ...

Schritt zurück ein wenig, versuchen und sehen das Holz nicht die Bäume. Ich war, wo man oft sind, sind Sie wahrscheinlich den falschen Baum (sorry pun intended) Bellen und wird in Kürze selbst alle möglichen Namen nennen:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top