AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Interface referenzen auf gleichheit prüfen?
Thema durchsuchen
Ansicht
Themen-Optionen

Interface referenzen auf gleichheit prüfen?

Ein Thema von maximov · begonnen am 11. Okt 2004 · letzter Beitrag vom 14. Okt 2004
Antwort Antwort
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#1

Re: Interface referenzen auf gleichheit prüfen?

  Alt 11. Okt 2004, 20:45
Nein, dein Weg funktioniert eben nicht. Der AS Operator ist ein verkapselter Aufruf von A.QueryInterface(var B, GUID: TGUID). D.h. der Code


Delphi-Quellcode:
  A := B as IInterfaceType

ist identisch mit

  if B.QueryInterface(A, IInterfaceType) <> S_OK then raise Exception.Create(...);
So erstmal der erste Schritt, nun der zweite:

Eine Impelentierende Klasse kann nun .QueryInterface() überschreiben und dynamisch auf Anforderung ein neues Implemntierendes Object erzeugen das die geforderte Schnittstelle implementiert, also in etwa so:

Delphi-Quellcode:
function TClassA.QueryInterface(var Unk; const GUID: TGUID): HResult; stdcall;
begin
  Result := S_OK;
  if GUID = IInterfaceType then IInterface(Unk) := TImplementorClass.Create
    else Result := inherited QueryInterface(Unk, GUID);
end;

In diesem Moment erzeugt also die Klasse TClassA ein ganz neues Object das die geforderte Schnittstelle IInterfaceType tatsächlich implementiert. Bei solch einer Implementierung, die sehr oft verwendet wird, kann dein einfacher Vergleich der Variablenpointer nicht mehr funktionieren, denn nun würde ja alles, selbst die Impelemntierende Klasse vollständig von der eigentlichen Klasse gekapselt sein.

Also sowas wie:

Delphi-Quellcode:
var
  A,B,C: IInterface;
begin
  A := TClassA.Create;
  
  B := A as IInterfaceType;
  C := A as IInterfaceType;

  Assert( B <> C );
end;
B ist immer ungleich C da der cast (A as IInterfaceType) -> A.QueryInterface() eben intern bei jeder Abfrage ein eigenes neues Interface erzeugt.


Zitat:
Es bleibt maximovs Einwand, dass diese Information eigentlich schon implizit vorhanden und gegeben ist durch die Identät des Objekts.
Und das stimmt eben nicht. Interfaces besitzen per Konzept keine Identität auf deren Implementierung und somit kann auch eine Delphi VCL Klasse nicht ihre implementierende und eindeutige Klassen-Identität auf deren implementierte Interfaces übertragen. Der Weg den die RT /bzw. der Delphi Compiler die Interfaces im Klassendesign über die RTTI umsetzt ist absolut Delphi typisch und nicht dokumentiert. Andere Compiler können das komplett anders handhaben.

Der Delphi Compiler legt im Codesegement die VMT des Interfaces als Konstante an. Die einzelnen Methoden dieses Interfaces zeigen eber nicht direkt auf die Methoden der implementierenden Klasse sondern auf Dispatcher Methoden die durch den Compiler erzeugt wurden. Für jede Methode im Interface gibt es eine eigene Dispatcher Funktion. Diese Dispatcherfunktion berechnet nun aus dem übergebenen Interface Zeiger per Offset den Self Zeiger des Objectes. Dieser Offset ist für jede Interface implementierende Klasse und für jedes einzelene Interface dieser Klasse selber unterschiedlich.

Nun, auch wenn man dies weis und als Ausgangsbasis für eine Identität zum direkten Vergleich von Interfacezegern heranziehen könnte, so ist diese Art und Weise der Impelemntierung von Interfaces eben Delphi typisch und zudem auch undokumentiert.

Nein, das was ich oben sagte stimmt auch weiterhin. Maximov sollte überlegen ob sein Konzept richtig ist, und ob er nicht zuviel von den Interfaces abverlangt. Mein oben vorgeschlagener Weg ist eine saubere Lösung, und für meine Begriffe die einzigst saubere überhaupt. Denn selbst wenn Delphi die Art und Weise wie es Interfaces mit Klassen/Objecten verbindet ändert, oder sogar wenn man auf diese Weise Interfaces die durch verschiedene Compiler erzeugt wurden, vergleicht, so funktioniert das immer sauber.

Gruß Hagen
  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 13:30 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