![]() |
Plugin-System mit Interfaces und DLLs
Hallo leutz,
ich bin momentan dabei ein Plugin-System für meinen ![]() Dabei habe ich mich für die Arbeit mit Interfaces und DLLs entschieden. Dies klappt im allgemeinen auch schon Recht gut. Ich durchsuche einen bestimmten Ordner nach dlls und lade diese nacheinander in einen Array, welcher alle nötigen Daten hält. Ein Object dieses Arrays erzeuge ich so (alle Variablen mit einem F werden gespeichert):
Delphi-Quellcode:
FPmInterface ist dabei das Interface der Hauptapplikation, welches immer an das Plugin übergeben wird, damit es mit der App interagieren kann..
constructor TPlugin.Create(Filename: String);
var Proc : TProcInitPlugin; begin inherited Create; FPmInterface:=TPmInterface.Create; FFilename:=Filename; FLib:=LoadLibrary(PChar(FFilename)); if FLib<>0 then begin @Proc:=GetProcAddress(FLib,'InitPlugin'); FPlugin:=Proc; FPluginInfo:=FPlugin.Init(FPmInterface); end; end; So, wie es hier ist, funktioniert es jetzt. Vorher hatte ich allerdings ein PmInterface, welches für alle Plugins gelten sollte (also nicht immer eins extra für jedes Plugin). Dies funktioniert aber irgendwie nicht, da nach jedem gebrauch das Objekt weg zu sein scheint, da ich immer eine Zugriffsverletzung bekomme, wenn ich es übergeben will. Ich weiss, dass sich die Objekte bei Interfaces selbst zerstören, wenn es keine Referenzen mehr aus sie gibt, aber ich habe doch eine Referenz ?!? das FPmInterface bleibt doch erhalten, auch wenn ich es übergebe ?!? Im Moment muss ich FPmInterface JEDESMAL neu erstellen, wenn ich es benutzen (sprich ans Plugin übergeben) möchte (da ich es im Plugin in jeder Funktion benutze, also immer). Gibt es da keine bessere Lösung? Mache ich etwas falsch?? Jemand eine Idee? greetz Steffen |
Re: Plugin-System mit Interfaces und DLLs
Hallo Steffen,
habe ein ähnliches Problem bei der Verwendung von Interfaces gehabt. Nachdem ich alle Interfaces per const übergeben habe, war das Problem gelöst. Delphi scheint einen Interface-Parameter ohne const am Ende der Funktion/Prozedur freizugeben. Da bei Dir der Referenzzähler auf 1 steht wird es freigegeben. Das eigentliche Objekt bekommt nichts davon mit und ist nach Aufruf der Funktion/Prozedur ungültig. Ich hoffe es hilft Dir weiter. Gruß Bernd |
Re: Plugin-System mit Interfaces und DLLs
Hallo,
ist FPmInterface ein TInterfacedObject oder ein Interface? Falls es ersteres ist, dann solltest Du das vergessen und nur das Interface speichern. Wenn Du nämlich ein TInterfacedObject erstellst und speicherts ist der Referenzzähler Null. Sobald Du dann das Interface benutzt wird der Referenzzähler erhöht und wieder vermindert -> Objekt wird freigegeben. Lästige Sache. ![]() Gruß xaromz |
Re: Plugin-System mit Interfaces und DLLs
erstmal danke für eure Antworten:
@bhenker: Werds mal ausprobieren, hatte das mit dem const aber in noch keinem Beispiel gesehen. @xaromz: Warum das passiert versteh ich jetzt, nur weiss ich nicht wie ich ohne das TInterfacedObject arbeiten soll. Ich muss das ja erzeugen, um der DLL mein Interface zu geben. greetz Steffen |
Re: Plugin-System mit Interfaces und DLLs
Hallo,
Zitat:
Delphi-Quellcode:
Stattdessen:
type
TMyClass = class(TInterfacedObject, IMyInterface) end; procedure MachWas(MyInterface: IMyInterface); begin // end; var MyClass: TMyClass; begin MyClass := TMyClass.Create; MachWas(MyClass); MyClass.Free; // <- hier knallts end;
Delphi-Quellcode:
Also durchgängig mit Interfaces arbeiten. Ich weiß aber gar nicht, ob Du sowas überhaupt machst.
var
MyInterface: IMyInterface; begin MyInterface := TMyClass.Create; MachWas(MyClass); MyInterface := nil; end; Bei Interfaces ist es übrigens tatsächlich immer ratsam, mit const zu arbeiten. Ich hab mich schon gefragt, warum Delphi das nicht automatisch macht. Gruß xaromz |
Re: Plugin-System mit Interfaces und DLLs
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Du definierst zuerst eine COM-Categorie mit Namen und GUID. Sowohl deiner Anwendung, als auch den Plugins ist diese GUID bekannt. Jedes Plugin registriert sich selbst mit dieser GUID. Die Anwendung sucht und findet die Plugins über diese GUID. Wo das Plugin auf der Platte liegt ist gleichgültig, es hindert dich aber niemand, alle in ein Verzeichnis zu packen. Eine DLL kann mehr als ein Plugin enthalten. |
Re: Plugin-System mit Interfaces und DLLs
@ xaromz:
mhh ok, versteh ich. Aber kann es bei mir nicht anwenden :/ Weil wenn ich das mit dem Interface statt der Klasse als Variablen mache, kann ich auch nur auf Funktionen zugreifen, welche das Interface beschreibt. Ich brauche aber noch weitere Funktionen innerhalb meine Applikation, die von außen zugänglich sind, aber nicht vom Plugin aus. Da steh ich gerade vor einem Problem :( Hab auch dein Beschriebenes prob: wärend der Laufzeit funktioniert alles, aber wenn ich das Prog schließe und die Objekte freigeben möchte, knallts :/ @ shmia: Danke für deine Idee, werd aber wohl erstmal bei Interfaces bleiben ;) greetz Steffen |
Re: Plugin-System mit Interfaces und DLLs
Hallo,
versuch mal folgendes:
Delphi-Quellcode:
Damit hebelst Du zwar den Garbage Collector etwas aus, aber wenn's läuft... :zwinker:
var
MyClass: TMyClass; begin MyClass := TMyClass.Create; MyClass._AddRef; // <- internen Zähler hochsetzen MachWas(MyClass); MyClass._Release; // <- internen Zähler runtersetzen, Objekt wird freigegeben //MyClass.Free; // <- das hier entfernen end; Gruß xaromz |
Re: Plugin-System mit Interfaces und DLLs
leider geht auch das nicht :(
Krieg da immer eine "invalid floating point operation". Egal ob ich es mit :=nil oder _Release mache ^^ :( greetz Steffen |
Re: Plugin-System mit Interfaces und DLLs
xaromz hat die Sache schon (fast) richtig erlärt:
Delphi-Quellcode:
var
MyInterface: IMyInterface; begin MyInterface := TMyClass.Create; MachWas(MyInterface); // "MyInterface" übergeben, nicht "MyClass" // MyInterface := nil; // diese Zeile sparen wir uns, da "MyInterface" automatisch "out-of-scope" gerät end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 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