AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Umgang mit Interfaces

Ein Thema von Whookie · begonnen am 5. Dez 2013 · letzter Beitrag vom 16. Dez 2013
Antwort Antwort
Seite 4 von 7   « Erste     234 56     Letzte »    
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#31

AW: Umgang mit Interfaces

  Alt 12. Dez 2013, 13:50
Ich habe in meinem Leben bislang nie den Mut gehabt, mir den Assemblercode anzuschauen, der für die Referenzzählung oder das Werfen einer Exception entsteht.

Dann würde ich jedes mal wenn ich in einer Methode mittels Interface-Variable über irgendetwas iterieren,ein schlechtes Gewissen bekommen und würde meines Lebens nicht mehr froh.


Ja, mir ging es jetzt nur um meinen persönlichen Komfort im Quelltext. Wie sehr der PC dann später zusätzlich schuften muss habe ich jetzt nicht bedacht...
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#32

AW: Umgang mit Interfaces

  Alt 12. Dez 2013, 14:13
Sehe ich das richtig, das mein MySomeThingObject bei Verlassen der Prozedur automatisch freigegeben wird, obwohl ich zuvor mit TMyDoSomething.Create; Speicher dafür alloziert habe ?
Wie oben erwähnt, ja!

Mit einem normalen Objekt hättest du ein Speicherleck!
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#33

AW: Umgang mit Interfaces

  Alt 12. Dez 2013, 14:36
Ja, mir ging es jetzt nur um meinen persönlichen Komfort im Quelltext. Wie sehr der PC dann später zusätzlich schuften muss habe ich jetzt nicht bedacht...
Wenn du Interfaces benutzt, sind es jeweils rund 15-20 Assemblerbefehle für das Hinzufügen der Referenz und das Entfernen. Es ist also nicht so furchtbar viel, läppert sich aber durchaus, wenn man damit intensiv arbeitet.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Patito

Registriert seit: 8. Sep 2006
108 Beiträge
 
#34

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 13:45
Wer meint es besser zu wissen bzw. sein Anwendungsfall es unbedingt erfordert, muss ja nicht von TInterfacedObject ableiten,
Die RefCount Methoden kann man zwar überschreiben, aber die Grundproblematik von Delphi wird man dadurch nicht los.
Delphi ruft z.B weiterhin lustig die Refenz-Count Methoden von Objekten auf, auch wenn das Objekt z.B. schon freigegeben wurde.
Die zur Zeit einzig sinnvolle Lösung für das Problem nennt sich Free-Pascal...

Die "automatische" Referenzverwaltung von Inferface-Objekten ist in meinen Augen sehr bequem und ermöglicht ein sehr komfortables modernes programmieren.
Ich denke, dass jemand, der "automatische" Referenzverwaltung für bequem hält, vom Thema insgesamt herzlich wenig verstanden hat.
Das ist fast genauso beknackt wie die Forderung der ActiveX Retro-Gurus, dass man Objekte und Interfaces nicht mischen sollte.

Leute. Nehmt einfach einen vernünftigen Compiler und reitet nicht für immer rum auf diesen Lehrsätzen für COM-Interfaces, die Microsoft mal in der Antike verkündet hat.

Hast du nur ein Objekt von Typ IInteger vorliegen, musst aber schauen ob ISomeThing unterstützt wird (oder umgekehrt) -> wie sollte man es sonst machen?
Ein Fehler (z.B. bei dem Problem mit der Liste) liegt schon an der Stelle, wo man so ein Objekt erzeugt und es dann in einen anonymen Container wirft. Eine bessere Lösung wäre die Objekte in typsicheren Listen zu speichern, und nicht erst zur Laufzeit die Objekte herauszufiltern. Wer Typsicherheit von der Compilezeit in die Laufzeit schiebt, darf sich nicht beschweren, dass es Probleme gibt.
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#35

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 13:49
Ich denke, dass jemand, der "automatische" Referenzverwaltung für bequem hält, vom Thema insgesamt herzlich wenig verstanden hat.
Oder ist es anders herum der Fall? Warum sollte ich als ahnungslos gelten, wenn ich z.B. ARC verwende? Unter ObjectiveC habe ich z.B. gar keine andere Wahl. Du verteidigst hier flammend FreePascal - das ist fein für Dich, aber ein klein wenig solltest Du dennoch über den Tellerrand schauen.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#36

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 14:32
Wer meint es besser zu wissen bzw. sein Anwendungsfall es unbedingt erfordert, muss ja nicht von TInterfacedObject ableiten,
Die RefCount Methoden kann man zwar überschreiben, aber die Grundproblematik von Delphi wird man dadurch nicht los.
Ehrlich gesagt kann ich dir jetzt nicht mehr so ganz folgen was denn die "Grundproblematik" sein soll.
Kannst du hierauf nochmal eingehen?
Das es COM-Interfaces sind - also einen gewissen sprachübergreifenden Standard folgen - ist jetzt aber nicht das "Problem", oder?

Delphi ruft z.B weiterhin lustig die Refenz-Count Methoden von Objekten auf, auch wenn das Objekt z.B. schon freigegeben wurde.
Die zur Zeit einzig sinnvolle Lösung für das Problem nennt sich Free-Pascal...
Dann lass es doch weiterhin lustig aufrufen.
Solange du in den selbstimplementierten _AddRef und _Release Methoden kein Schindluder betreibst geht das doch?!?
Wo ist das Problem?
Oder verhält sich das in Free-Pascal anderes?

Delphi-Quellcode:
  ISomeThing = Interface(IInterface)
  ['{16CCA417-F4C4-4B4A-88CE-FDD79B875876}']
    function DoSomeThing : Integer;
  End;

  TMyInterfacedObject = class(TObject, IInterface)
  protected
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;

  TMyDoSomething = Class(TMyInterfacedObject, ISomeThing)
  protected
    function DoSomeThing : Integer;
  end;

...

function TMyInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GetInterface(IID, Obj) then
    Result := 0
  else
    Result := E_NOINTERFACE;
end;

function TMyInterfacedObject._AddRef: Integer;
begin
  Result := -1;
end;

function TMyInterfacedObject._Release: Integer;
begin
  Result := -1;
end;

...

var
  MySomeThingObject : ISomeThing;
begin
  MySomeThingObject := TMyDoSomething.Create;
  MySomeThingObject.DoSomeThing;
  (MySomeThingObject as TMyDoSomething).Free;

  // folgendes funktioniert problemlos, obwohl das Objekt freigeben wurde!
  MySomeThingObject._AddRef;
  MySomeThingObject._AddRef;
  MySomeThingObject._AddRef;
  MySomeThingObject._Release;
end;


Die "automatische" Referenzverwaltung von Inferface-Objekten ist in meinen Augen sehr bequem und ermöglicht ein sehr komfortables modernes programmieren.
Ich denke, dass jemand, der "automatische" Referenzverwaltung für bequem hält, vom Thema insgesamt herzlich wenig verstanden hat.
Das ist fast genauso beknackt wie die Forderung der ActiveX Retro-Gurus, dass man Objekte und Interfaces nicht mischen sollte.

Leute. Nehmt einfach einen vernünftigen Compiler und reitet nicht für immer rum auf diesen Lehrsätzen für COM-Interfaces, die Microsoft mal in der Antike verkündet hat.
Ja nun, ich denke mir mal meinen Teil dazu.
Es gab immer Leute die meinen es besser zu wissen.

COM ist aktueller denn je, weiß nicht was das mit Antike zu tun haben sollte.
Mein Rechner läuft auf Windows 8.1 und da ist das "Kachelstartmenü" durchgehend mit dieser Technologie umgesetzt.

Zeige uns doch bitte mal einen typischen Anwendungsfall in deiner Applikation, wo der Einsatz von COM-Interfaces zu Fehlern führt und stattdessen das von dir gewünschte Verhalten besser wäre.

In meiner Applikation sind ein Großteil der Klassen über Interfaces ansprechbar und das nicht mischen von Objekt- und Interfacereferenzen gewöhnt man sich auch schnell an.
Weiß nicht worin da die Schwierigkeit besteht das konsequent durchzuziehen.
Gleichermaßen könnte man sich darüber aufregen, dass der Compiler nicht folgendes zur Compilezeit anmeckert:

Delphi-Quellcode:
 
var
  a, b, c : Integer;
begin
  a := 0;
  c := b div a;
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#37

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 14:39
Delphi ruft z.B weiterhin lustig die Refenz-Count Methoden von Objekten auf, auch wenn das Objekt z.B. schon freigegeben wurde.
Dann liegt der Fehler aber auch bei dir.

Wenn du "referenzählende" Variablen hast, und du denen unterm Arsch weg die Objekte klaust, wovon die natürlich nichts mitbekommen,
dann können die nur davon ausgehen, daß die darin verlinkte Instanz gültig ist und es werden die Referenzen gezählt (bzw. es wird versucht).

- Entweder es wird über die Referenzzählung der Speicher freigegeben
- und wenn nicht, dann darf die Variable nicht referenzzählend sein
- oder du mußt die referenzzählende Variable auf nil setzen (unter böswilliger Umgehung der Referenzzählung), sobald du das Objekt freigibst, oder bevor die Variable freigegeben wird, bzw. bevor sie einen neuen Wert bekommt

- und es darf auch keiner mehr die "ungültige" Referenz daraus verwenden



Gleichermaßen könnte man sich darüber aufregen, dass der Compiler nicht folgendes zur Compilezeit anmeckert:
Der meckert doch?

B ist nicht initialisiert


// folgendes funktioniert problemlos, obwohl das Objekt freigeben wurde!
Die Speicherverwaltung ht den speicher aber "oftmals" noch nicht sofort freigegeben.

Das kann man aber zum Debuggen beheben.
- FastMM entsprechend einstellen
- oder einen Debug-Speichermanager verwenden

welche die Objektinstanzen zerstören/überschreiben, womit des beim nächsten Zugriff knallt


PS: Zugrif auf "ungültige" Zeiger .... wie oben erwähnt.
Das Objekt ist weg, aber DU hast den Instanzzeiger in MySomeThingObject nicht bereinigt.
$2B or not $2B

Geändert von himitsu (13. Dez 2013 um 14:48 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#38

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 15:23
Gleichermaßen könnte man sich darüber aufregen, dass der Compiler nicht folgendes zur Compilezeit anmeckert:
Der meckert doch?

B ist nicht initialisiert


PS: Zugrif auf "ungültige" Zeiger .... wie oben erwähnt.
Das Objekt ist weg, aber DU hast den Instanzzeiger in MySomeThingObject nicht bereinigt.
Eben das wollte ich zeigen!
Solange der Pointer nicht ungültig wird, wird ja auch beliebig in die Methoden gesprungen.
Wenn hier fröhlich Interface- und Objektreferenzen gemischt werden (sollt ihr dafür alle in der Hölle schmoren) dann geht auch folgends:
Delphi-Quellcode:
function TMyDoSomething.DoSomeThing : Integer;
begin
  Result := 123;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  MySomeThingObject : TMyDoSomething;
  MagicNumber : Integer;
begin
// MySomeThingObject := TMyDoSomething.Create;
  MagicNumber := MySomeThingObject.DoSomeThing;
// MagicNumber hat jetzt den Wert 123, obwohl kein Objekt erzeugt wurde! Schwarze Magie? ;-)
end;
Von daher soll der Compiler doch ruhig in die eigenen _AddRef- und _Release-Methoden springen, wenn man meint sowas brauchen zu müssen!
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
445 Beiträge
 
Delphi 10.3 Rio
 
#39

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 18:18
Ich seh schon ... heißes Thema ...

Da es mir aber um die Implementierung mit Interfaces geht habe ich das ganze nochmals vereinfacht und komplett auf Interfaces umgestellt. Dazu gibts ein eigenes IAdmin-Interface in dem die Sachen definiert sind die vorher eben nur in der Objektinstanz zur Verfügung standen.

Die Implementierung habe ich hier angehängt weil es noch ein Problem bei der Verwaltung der Interfaces gibt und ja, ohne FastMM gibts keine vernünftige Delphi-Entwicklung !

Nochmals zur Erklärung: Die "Hauptliste" (fIntfLst) wird aus einer Textdatei erstellt, es gibt um die 20 verschiedenen Klassen die aus der Kombination von ca. 10 Interfaces bestehen. Diese "Knoten" stehen noch untereinander in Beziehung und daher speichern die Knoten diese Beziehungen in privaten Listen (wie z.B.: TTest.fMyNodes)...

Eigentlich dachte ich ja, das bei reiner Interface-Verwendung keine Probleme mehr auftreten, aber irgendwie schaffe ich es durch meine Querverlinkung die Referenzzählung durcheinander zu bringen (siehe uImpl.pas Zeile 170)...
Angehängte Dateien
Dateityp: 7z Interface_tests.7z (2,6 KB, 4x aufgerufen)
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#40

AW: Umgang mit Interfaces

  Alt 13. Dez 2013, 19:29
Wenn der Speichermanager aufräumt, dann wird es auch knallen. Oder wenn inzwischen etwas Anderes an der Stelle steht, dann produziert man damit einen Buffer-Overrun,
wenn man auf ungültige Variablen zugreift.

Und das ist nicht erst seit Interfaces so.
Delphi-Quellcode:
var
  o: TMyIrgendwas;

o := TMyIrgendwas.Create;
o.Free;
o.DoWas; // Fehler

o := TMyIrgendwas.Create;
FreeAndNil(o);
o.DoWas; // Zugriffsverletzung bei Addresse 0


Man kann gern die Speicherverwaltung komplett der Referenzzählung des Interfaces überlassen.

Und wenn es unbedingt sein muß, dann holt man sich "kurzzeitig" nochmal eine Objekt-Referenz aus dem Interface raus (an dieser Stelle muß parallel eine Interface-Referenz vorhanden sein), denn Delphi bietet seit einer Weile ein Pseudo-Interface an, welches die Objektreferenz zurückgibt. (wenn im Interface ein Delphi-Objekt steckt)
Und an diese Objektreferenz kommt man z.B. via intf AS TObject ran.
Man kann natürlich auch eigene Getter in seinem Interface verbauen, welches Objekt-Instanzen zurückgibt.
Sobald dann die "paralelle" Interface-Referenz freigegeben wird, ist die Objektreferenz als "ungültig" anzusehen.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 7   « Erste     234 56     Letzte »    


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 22:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz