AGB  ·  Datenschutz  ·  Impressum  







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

TInterfaceList und lokale Referenzen

Ein Thema von lizardking · begonnen am 19. Jun 2006 · letzter Beitrag vom 26. Jul 2006
Antwort Antwort
lizardking

Registriert seit: 2. Sep 2005
76 Beiträge
 
Delphi 7 Enterprise
 
#1

TInterfaceList und lokale Referenzen

  Alt 19. Jun 2006, 23:29
Hi zusammen,

hab gerade was, was mich extrem stutzig macht.
Kurze Erlaeuterung:

Ich lade Plugin-DLLs und speichere deren Interfaces(ITWPLugin) in eine TInterfaceList(FPLugins). In einer Funktion UnloadAllPlugins sollen die Eintraege in der Liste geloescht und die jeweilige DLL entladen werden (Handle zur DLL wird im Plugin gespeichert).
Folgender Code funktioniert (ist aber sehr unschoen):

Delphi-Quellcode:
function TTWPluginManager.RemovePlugins: TStringList;
var
  i: Integer;
  LHandle: THandle;
  LPlugin: ITWPlugin;
begin
 result := TStringList.Create;
 for i := FPlugins.Count - 1 downto 0 do
 begin
   LHandle := (FPlugins.Items[i] as ITWPlugin).Handle;
   result.Add(inttostr(LHandle));
   FPlugins.Delete(i);
  end;
end;

function TTWPluginManager.UnloadAllPlugins: Boolean;
var
  i: Integer;
  LHandle: THandle;
  HandleList: TStringList;
begin
  HandleList := RemovePlugins;
  for i := 0 to HandleList.Count - 1 do
  begin
   LHandle := StrToInt(HandleList[i]);
   FreeLibrary(LHandle);
  end;
  HandleList.Free;
end;
UnloadAllPlugins ruft quasi die Hilfsfunktion RemovePlugins auf, die in einer TStringList die Handles zurueckliefert, die entladen werden koennen und entlaedt diese entsprechend. Wenn ich jetzt aber versuche das in eine Funktion zu packen, so bekomme ich 'ne AV beim FreeLibrary. Ich kann mir das nur so erklaeren, dass im Scope von RemovePlugins zusaetzliche Referenzen zu den Plugin-Interfaces entstehen. Deshalb gibt's die AV, ich versuche halt eine Library zu entladen, von der noch Objekte vorhanden sind. Verlasse ich den Scope von RemovePlugins, so werden diese Referenzen natuerlich geloescht und die Objekte korrekterweise zerstoert.

Aber an welcher Stelle schaffe ich mir diese lokalen Referenzen ?

Bin fuer jeden Hinweis dankbar. Hab zwar diesen funktionierenden Workaround, aber gerade an 'ner Pluginschnittstelle will ich nicht direkt mit Pfusch anfangen ;-)

Gruesse,

Lizzy
  Mit Zitat antworten Zitat
andreash

Registriert seit: 22. Jun 2006
Ort: Dörverden
60 Beiträge
 
Delphi 7 Professional
 
#2

Re: TInterfaceList und lokale Referenzen

  Alt 25. Jun 2006, 15:53
Hallo!

Meine Vermutung ist, dass die Zeile
  LHandle := (FPlugins.Items[i] as ITWPlugin).Handle; den Fehler verursacht. Der Referenzzähler müsste beim Ausführen hochgezählt werden und wird wohl erst nach Beenden der Routine frei gegeben.

Versuche es doch einmal so:

Delphi-Quellcode:
...
for i := FPlugins.Count - 1 downto 0 do
begin
  LPlugin := (FPlugins.Items[i] as ITWPlugin);
  LHandle := LPlugin.Handle;
  result.Add(inttostr(LHandle));
  FPlugins.Delete(i);
End;
LPlugin := Nil;
...
Getestet habe ich es nicht.
Andreas
Der Optimist glaubt, wir leben in der besten aller möglichen Welten. Der Pessimist befürchtet, daß das stimmt.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

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

Re: TInterfaceList und lokale Referenzen

  Alt 25. Jun 2006, 20:46
Kommt der Interfacezeiger (ITWPLugin) aus der DLL? Wie schaut die entsprechende Funktion aus der DLL aus?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
lizardking

Registriert seit: 2. Sep 2005
76 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: TInterfaceList und lokale Referenzen

  Alt 2. Jul 2006, 22:41
@Andreas
Der Code arbeitet so wie gepostet schon korrekt. Unschoen ist nur, dass ich auf diese Hilfsfunktion angewiesen bin und nicht alles in einer Prozedur ausfuehren kann.

Zitat von Bernhard Geyer:
Kommt der Interfacezeiger (ITWPLugin) aus der DLL? Wie schaut die entsprechende Funktion aus der DLL aus?
Jepp, der Interface-Zeiger kommt aus der DLL. Die exportierte Funktion dabei ist recht unspektakulaer:

Delphi-Quellcode:
function GetPlugin(APluginManager: ITWPluginManager): ITWPlugin;
begin
  result := TExamplePlugin.Create(APluginManager);
end;
TExamplePlugin ist dabei abgeleitet von einer Klasse TTWPlugin, die das Interface ITWPlugin implementiert.

Gruesse,

Lizzy
  Mit Zitat antworten Zitat
andreash

Registriert seit: 22. Jun 2006
Ort: Dörverden
60 Beiträge
 
Delphi 7 Professional
 
#5

Re: TInterfaceList und lokale Referenzen

  Alt 5. Jul 2006, 21:45
Vielleicht funktioniert es so
Delphi-Quellcode:
function TTWPluginManager.UnloadAllPlugins: Boolean;
Var
  i: Integer;
  LHandle: THandle;
  LPlugin: ITWPlugin;
begin
  for i := FPlugins.Count - 1 downto 0 do
  begin
    LPlugin := (FPlugins.Items[i] as ITWPlugin);
    LHandle := LPlugin.Handle;
    LPlugin := Nil;
    FPlugins.Delete(i);
    FreeLibrary(LHandle)
  end;
End
Ich halte noch an der These fest, dass
LHandle := (FPlugins.Items[i] as ITWPlugin).Handle; den Referenzzähler hochzählt und zu spät wieder herunterzählt.

Andreas
Der Optimist glaubt, wir leben in der besten aller möglichen Welten. Der Pessimist befürchtet, daß das stimmt.
  Mit Zitat antworten Zitat
lizardking

Registriert seit: 2. Sep 2005
76 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: TInterfaceList und lokale Referenzen

  Alt 8. Jul 2006, 23:16
Zitat von andreash:
Ich halte noch an der These fest, dass
LHandle := (FPlugins.Items[i] as ITWPlugin).Handle; den Referenzzähler hochzählt und zu spät wieder herunterzählt.

:duck:
Hab's jetzt mal auf Deine Weise ausprobiert und... naja. Funktioniert (wie ich erwartet hab) auch nicht :cry:
  Mit Zitat antworten Zitat
lizardking

Registriert seit: 2. Sep 2005
76 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: TInterfaceList und lokale Referenzen

  Alt 26. Jul 2006, 21:42
Zitat von andreash:
Ich halte noch an der These fest, dass
LHandle := (FPlugins.Items[i] as ITWPlugin).Handle; den Referenzzähler hochzählt und zu spät wieder herunterzählt.

Tada

Ich geb Dir jetzt mal zu 50% Recht . Okay, sogar etwas mehr als 50%. Es ist in der Tat so, dass genau in dieser Zeile der ... aeh... nein... DIE Referenzzaehler hochgezaehlt werden. Und zwar passiert naemlich Folgendes:

1. Holen des Interfaces aus FPlugins -> Erhoeht Ref.-Zaehler fuer IInterface
2. Cast auf ITWPlugin -> Erhoeht Ref.-Zaehler fuer ITWPlugin

Dann ist auch das klar:

Delphi-Quellcode:
procedure Foo();
var
  x: ITWPlugin;
begin
  x := FPLugins[0] as ITWPlugin;
  x := nil;
end;
Referenzzaehler fuer ITWPlugin geht natuerlich auf 0. Aber: Referenzzaehler fuer IInterface wird erst nach beenden der Prozedur runtergezaehlt und dementsprechend erst dann das Objekt zerstoert.

In dem Sinne, Danke fuer die Antworten. Jetzt kann ich wieder ruhig schlafen *g*. Thema ist somit geklaert

Gruesse,

Lizzy
  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 09:39 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