AGB  ·  Datenschutz  ·  Impressum  







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

Interface und Zugriffsverletzung

Ein Thema von _frank_ · begonnen am 22. Jul 2007 · letzter Beitrag vom 22. Jul 2007
Antwort Antwort
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#1

Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 02:04
Guten morgen,

ich habe mal versucht, mich bisschen mit Interfaces zu beschäftigen, da ich meinen DFM-Editor in näherer Zukunft mit Plugins ausstatten möchte. So wie es aussieht, eigenen sich interfaces dafür am besten.
hab mir bezüglich Plugins folgendes durchgelesen:
http://www.delphipraxis.net/internal...ect.php?t=5390
hier hat aber das plugin scheinbar nicht die Möglichkeit das Hauptprogramm zu steuern, was mit interfaces möglich ist.
im folgenden Thread werden Interface-Plugins erläutert:
http://www.delphipraxis.net/internal...ect.php?t=4203
der code scheint nicht ganz vollständig zu sein. es wird auch das problem mit der Zugriffsverletzung angesprochen, jedoch die "lösung" entfernt meine AV leider nicht
genau sinds 2 Exceptions, eine beim freigeben der dll (scheinbar bereits freigegebenes Objekt) und eine beim beenden (nil-pointer, jedoch ist das app-objekt noch gültig).

ich hänge mal das komplette Test-Programm an...hoffe es kennt sich jemand etwas besser aus und kann mir sagen, warum die exceptions kommen bzw. wie man diese entfernen kann.

Gruß Frank
Angehängte Dateien
Dateityp: zip plugintest_676.zip (148,7 KB, 7x aufgerufen)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 07:00
Hallo,

ohne jetzt überhaupt reinzuschauen

Interfaces unter Delphi sind COM-Interfaces.
Die daranhängendenden Objekte werden "wild" freigegeben,
wenn das Interface seine Gültigkeit verliert.

Wird das Interface z.B. als lokale Variable definiert,
wird nach Beenden der Methode auch das Objekt freigegeben.
Da muss man dann Rumtricksen mit _AddRef und Release.
Deine Interfaces müssen die beiden Methoden überschreiben
und dort gar nichts tun, also keine Referenz hochzählen und Runterzählen.
Das Interface muss dann selber wieder freigegeben werden
(auf NIL setzen reicht wohl nicht).


Ich bin da auch schön reingefallen.

Ich wollte ein c# Bsp 1:1 nach Delghi übersetzen
und hatte auch AV ohne Ende.

Setze mal einen Breakpoint auf den Destructor der Klasse,
dann siehst du, was ich meine.


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#3

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 12:00
Zitat von hoika:
Hallo,

ohne jetzt überhaupt reinzuschauen

Interfaces unter Delphi sind COM-Interfaces.
Die daranhängendenden Objekte werden "wild" freigegeben,
wenn das Interface seine Gültigkeit verliert.
na super
Zitat von hoika:
Wird das Interface z.B. als lokale Variable definiert,
wird nach Beenden der Methode auch das Objekt freigegeben.
Da muss man dann Rumtricksen mit _AddRef und Release.
Deine Interfaces müssen die beiden Methoden überschreiben
und dort gar nichts tun, also keine Referenz hochzählen und Runterzählen.
Das Interface muss dann selber wieder freigegeben werden
(auf NIL setzen reicht wohl nicht).
mhm...hab das mal probiert, habe zwar die nil-Pointer-exception nicht mehr, aber die bei freigeben der dll bleibt
und wie geb ich das interface dann frei? free gibts ja nicht...
Zitat von hoika:
Setze mal einen Breakpoint auf den Destructor der Klasse,
dann siehst du, was ich meine.
ehrlich gesagt, ich seh nichts

Gruß Frank
Angehängte Dateien
Dateityp: zip plugintest_374.zip (148,9 KB, 5x aufgerufen)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 12:39
Hallo,

> ich seh nix

beim Verlassen des Gültigkeitsbereiches eines
Interfaces wird nicht nur das Interface "gelöscht",
sondern auch das betroffene Objekt gelöscht.

Abhilfe bringt nur _AddRef und Release zu überschreiben
und dort nichts tun (Referenzzählung deaktivieren).

Ein Interface wird normalerweise freigegeben,
wenn es auf NIL gesetzt wird.

Probier mal mit memcheck, ob das reicht.


Ich hatte nach dem einen Test so die "Schnauze voll",
dass ich erst wieder was mit machen werden,
wenn delphi.net bei uns ansteht.


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#5

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 13:24
Zitat von hoika:
Hallo,

> ich seh nix

beim Verlassen des Gültigkeitsbereiches eines
Interfaces wird nicht nur das Interface "gelöscht",
sondern auch das betroffene Objekt gelöscht.

Abhilfe bringt nur _AddRef und Release zu überschreiben
und dort nichts tun (Referenzzählung deaktivieren).
das hab ich ja gemacht...
Delphi-Quellcode:
//anwendungsseite
function TApp._AddRef: Integer; stdcall;
begin
  //
end;

function TApp._Release: Integer; stdcall;
begin
  //
end;

function TMemoWrapper._AddRef: Integer;
begin
  //
end;

function TMemoWrapper._release: Integer;
begin
  //
end;

//plugin-seite
function TPlugin._AddRef: Integer;
begin
  //
end;

function TPlugin._release: Integer;
begin
  //
end;
die variable app:TApp ist im Gültigkeitsbereich der form, ist auch im destroy des forms korrekt gesetzt (inkl. Interface auf Ieditor), wo es dann freigegeben wird. Es kommt auch keine nil-pointer exception beim beenden mehr...

muss ich vor dem freigeben der dll das TPlugin-Objekt irgendwie freigeben, oder reicht das per nil-Zuweisung beim Interface anwendungsseitig? (habs zumindest nicht ohne AV hinbekommen)

Zitat von hoika:
Ein Interface wird normalerweise freigegeben,
wenn es auf NIL gesetzt wird.

Probier mal mit memcheck, ob das reicht.

Ich hatte nach dem einen Test so die "Schnauze voll",
dass ich erst wieder was mit machen werden,
wenn delphi.net bei uns ansteht.
vielleicht findet ja auch jemand anderes Lust, der sich auskennt
gibt sicher ne ganz triviale lösung...so umfangreich ist es ja (noch) nicht...kanns nur nicht richtig nachvollziehen, warum die AV kommt. Muss man evtl irgendwas festes bei den beiden funktionen zurückgeben? weil so sind die ja undefiniert...

Gruß Frank
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#6

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 14:05
Hallo,

mit _AddRef und _Release würde ich erst experimentieren, wenn ich mich gut mit Interfaces auskenne.
Ich habe Dein Beispiel aus dem ersten Beitrag mal etwas überarbeitet und folgende Änderungen vorgenommen:
  • Instanzen und Interfaces nicht mehr gemischt (IApp/TApp). Diese niemals mischen (siehe oben: man sollte genau wissen, was man tut)
  • Interfaces werden per const übergeben (dadurch wird die Referenzzählung nicht belastet)
  • DLL wird beim Programmstart geladen und beim Beenden entladen
  • IApp ist von Form1 entkoppelt
Du solltest nie eine DLL entladen, wenn Du in der Methode ein lokales Interface dieser DLL hast. Beim Beenden der Funktion sorgt die Compiler-Magic nämlich dafür, dass das Interface abgebaut wird. Wenn aber die DLL bereits entladen ist, dann gibt's eine AV.

Gruß
xaromz
Angehängte Dateien
Dateityp: zip plugintest_240.zip (259,1 KB, 8x aufgerufen)
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#7

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 15:07
Zitat von xaromz:
Hallo,
Hallo, und danke dir erstmal, funktioniert schonmal super
Zitat von xaromz:
mit _AddRef und _Release würde ich erst experimentieren, wenn ich mich gut mit Interfaces auskenne.
naja, kenn ich ja noch net aus damit, und hab ich ja auch nur, um die AVs wegzubekommen
Zitat von xaromz:
Ich habe Dein Beispiel aus dem ersten Beitrag mal etwas überarbeitet und folgende Änderungen vorgenommen:
  • Instanzen und Interfaces nicht mehr gemischt (IApp/TApp). Diese niemals mischen (siehe oben: man sollte genau wissen, was man tut)
  • Interfaces werden per const übergeben (dadurch wird die Referenzzählung nicht belastet)
  • DLL wird beim Programmstart geladen und beim Beenden entladen
  • IApp ist von Form1 entkoppelt
das mit dem mischen hab ich noch nicht ganz verstanden...du übergibst doch auch ein interface an die klasse TApp beim create (bzw. wird das memo-Objekt als Interface weitergegeben). TMemoWrapper wird wohl selbst auch als Interface interpretiert bzw. gibt dessen contructor das Interface zurück, was in der deklaration (class(TInterfacedObject, IEditor)) angegeben wurde?

zu dem entkoppeln...muss ich mal schauen, wie ich das dann mache wenn ich zugriff auf mehrere Objekte brauche, momentan ists ja zum test nur das memo...
Zitat von xaromz:
Du solltest nie eine DLL entladen, wenn Du in der Methode ein lokales Interface dieser DLL hast. Beim Beenden der Funktion sorgt die Compiler-Magic nämlich dafür, dass das Interface abgebaut wird. Wenn aber die DLL bereits entladen ist, dann gibt's eine AV.
und bei globalen/"form-gültigen" interface-Typen ist das nicht so? versteh ich nicht so ganz...naja Compiler-Magic

hab zumindest erstmal einen funktionierenden startpunkt und paar Infos, den rest muss ich ausprobieren bzw. schauen, was ich so dazu finde
werde mir den Source so nochmal in einer Ruhigen minute zu Gemüte führen, habs jetzt nur überflogen und die änderungen gesucht bzw. deine Punkte daran nachvollzogen (zumindest versucht)

wird eh erst eingebaut, wenn (endlich mal) die Background-Klasse für den DFM-Editor fertig ist und eingebaut ist...ist auch massig Arbeit, das alles anzupassen. wollte das nur im vorfeld schonmal bisschen probieren. Dem Interface wird dann diese Background-Klasse übergeben, welche sich per Event um das Treeview kümmert und das Plugin rührt dann nicht in der vcl (wenn auch indirekt) rum... maximal bei Menüeinträgen, aber da muss aich auch schauen, wie ich das mit der toolbar (besonders den Glyphs) mache.

Gruß Frank
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#8

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 16:19
Hallo,

was das Mischen von Instanzen und Interfaces angeht kann ich Dich an meine Einführung in Interfaces verweisen.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Interface und Zugriffsverletzung

  Alt 22. Jul 2007, 16:46
Zitat von hoika:
Interfaces unter Delphi sind COM-Interfaces.
Die daranhängendenden Objekte werden "wild" freigegeben,
wenn das Interface seine Gültigkeit verliert.
Das kann ich so nicht stehen lassen:

1, Interfaces unter Delphi sind an COM angelehnt, aber funktionieren wunderprächtig auch Delphi-Intern und auch unter Linux (Kylix)
2, Sie werden (im Gegensatz zu .NET) nicht "wild" freigegeben (die "dahinterliegende" Instanz eines Objekts) sondern sofort wenn es keinen Interfacezeiger mehr darauf gibt (Referenzzählung). Nur wenn man den Tipp von xaromz (Keine Mischverwendung Instanzen und Interfaces) nicht berücksichtigt bekommst man Probleme mit der Delphi-Implementierung von Interfaces).

Zitat von hoika:
Wird das Interface z.B. als lokale Variable definiert,
wird nach Beenden der Methode auch das Objekt freigegeben.
Da muss man dann Rumtricksen mit _AddRef und Release.
Und wieso das? Wenn die Variable/Interface lokal ist dann sollte sie doch freigeben werden nach dem Verlassen. Du hast ja auch keine Variable mehr um darauf zuzugreifen.

Wenn man 2-3 Fallen der Delphi-Implementierung umschifft dann sind Interfaces in Delphi (im Gegensatz z.B. zu C/C++, auch mit Smartpointer) easy zu verwenden und auch sehr Pflegeleicht.
Windows Vista - Eine neue Erfahrung in Fehlern.
  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 08:30 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