AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi TNotifyEvent Objektbezogen in Variable speichern #2
Thema durchsuchen
Ansicht
Themen-Optionen

TNotifyEvent Objektbezogen in Variable speichern #2

Offene Frage von "einbeliebigername"
Ein Thema von berens · begonnen am 16. Jan 2012 · letzter Beitrag vom 17. Jan 2012
Antwort Antwort
berens

Registriert seit: 3. Sep 2004
441 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: TNotifyEvent Objektbezogen in Variable speichern #2

  Alt 16. Jan 2012, 21:28
Scheint auf den ersten Blick einwandfrei zu funktionieren. Vielen Dank erstmal hierfür

Das mit
Delphi-Quellcode:
 TMethod = record
    Code, Data: Pointer;
  end;
wurde ja schon im vorhergehenden Thread glaube ich erwähnt, aber das habe ich jetzt nicht weiter beachtet, denn:

Wenn mein "Event" ja in Wirklichkeit (nur) ein Pointer auf eine Instanz von TMethod ist, müssen die Pointer von a.Pressed und b.Pressed ja zwangsläufig verschiedene Speicherbereiche (also PointerAdressen) haben, da beide auf ein anderes Objekt verweisen. Sonst würde ja im regulären Programmablauf b.Pressed tatsächlich a.Pressed aufrufen.

Als muss irgendwas mit dem @ nicht stimmen. Ich habe zwar schon mehrere Tutorials zu Pointer gelesen, aber gerade auch wieder aufgrund der aktuellen Problematik blicke ich da (wieder) nicht durch.

Ich könnte mir denken, dass der einfache @ Vergleich nur dann zulässig ist (bzw. funktioniert) denn der Pointer auf eine einfache Variable verweist (Int, String, ...).

Wenn mir jetzt einfach jemand sagt, dass @Pointer oder Klassen(de?)referenz^ mit Dach^ eh nur noch Überbleibsel aus früheren Zeiten sind, die in aktuellen Programmen gar nichts mehr verloren haben, wäre ich Euch echt sehr dankbar!

Vielen Dank für Hilfe, Thema einstweilen erledigt.
N8
  Mit Zitat antworten Zitat
einbeliebigername

Registriert seit: 24. Aug 2004
140 Beiträge
 
Delphi XE8 Professional
 
#2

AW: TNotifyEvent Objektbezogen in Variable speichern #2

  Alt 17. Jan 2012, 00:37
Hallo,

Wenn mein "Event" ja in Wirklichkeit (nur) ein Pointer auf eine Instanz von TMethod ist
Ne, ein Event ist direkt das TMethod. Habe zur Veranschaulichung deine Methode um par Debug-Hilfen ergänzt:
Delphi-Quellcode:
function TForm1.IndexOfEvent(const _Event: TNotifyEvent): Integer;
var
  i: Integer;
  a: Integer;
  E: TNotifyEvent;
  b: Integer;
begin
  Result := -1;
  // Siehe Oben: Mein Ziel: Wenn von GENAU DIESEM Object (a.Pressed, b.Pressed),
  // GENAU DIESES Event gefunden wird, dann gebe dessen Index zurück

  // wird bei RegisterEvent(a.Pressed) NICHT durchlaufen, da hier FListSubscriber.Count noch 0 ist!
  for i := 0 to FListSubscriber.Count - 1 do begin
    a:= SizeOf(TNotifyEvent);
    E:= THAL_ObserverItem(FListSubscriber[i]).Event;
    b:= SizeOf(TMethod);
    OutputDebugString(PChar(Format('TMethod(T.Event).Code= %p; TMethod(T.Event).Data= %p; @E= %p; Int64(@E)= %d; @@E= %p; SizeOf(TNotifyEvent)= %d; SizeOf(TMethod)= %d; @a= %p; @b= %p; @i= %p ', [TMethod(E).Code, TMethod(E).Data, @E, Int64(@E), @@E, a, b, @a, @b, @i])));
    if (TMethod(THAL_ObserverItem(FListSubscriber[i]).Event).Data = TMethod(_Event).Data) and (TMethod(THAL_ObserverItem(FListSubscriber[i]).Event).Code = TMethod(_Event).Code) then
      // ^-- HIER ist das Hauptproblem: Sei _Event = b.Pressed ergibt der Vergleich True, obwohl bisher nur a.Pressed in der Liste ist!
    begin
      Result := i;
      Exit;
    end;
  end;
end;
Raus kommt dann das:
Code:
Debug-Ausgabe: TMethod(T.Event).Code= 004CBE40; TMethod(T.Event).Data= 028D3870; @E= 004CBE40; Int64(@E)= 5029440; @@E= 0018FE5C; SizeOf(TNotifyEvent)= 8; SizeOf(TMethod)= 8; @a= 0018FE4C; @b= 0018FE48; @i= 0018FE50  Prozess dp165785Project1.exe (10976)
Da sieht man, dass eine Variable vom Typ TNotifyEvent bereits so groß ist wie zwei Pointer. Bei dem @ und Methoden-Zeigern greift wiedermal ein wenig Compiler-Magie. Eigentlich gibt das @ die Adresse des dahinter stehenden Ausdrucks zurück. Bei @a bekommt man im obigen Beispiel die Adresse, wo die Variable a auf dem Stack liegt, zurück. Bei Methoden-Zeigern gibt das @ den Inhalt der Variable zurück. Die Adresse der Variable bekommt man erst mit einem @@ zurück. Wieso jetzt aber das einfache @ bei Methoden-Zeigern nur die Hälfte des Inhaltes wiedergibt, bleibt mir ein Rätsel.

Leider habe ich gerade kein lauffähiges Delphi 7 zur Verfügung. Denn ich bin der Meinung das der Vergleich mit dem @ da noch funktioniert hat. Vielleich sind ja andere so nett und Testen das mal mit anderen Versionen. Ich habe das mit Delphi 2007, XE und jetzt sogar mit XE2 Update 3 in 32 und 64bit getestet. Immer mit dem gleichen Ergebnis. Nur das sich bei 64bit die Größen verdoppeln. Und da liegt vermutlich auch das Problem. Laut Hilfe von XE2 gibt es unter 64bit kein 128bit großen Datentyp äquivalent zu Int64 bei 32bit, so das gar nicht beide Pointer bei dem @ zurückgegeben werden können.

Auch TControlActionLink.IsOnExecuteLinked und DelegatesEqual sehen bei XE2 so aus wie bei XE.

Einbeliebigername.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz