Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Runtime-Package gibt Pointer auf ein Interface zurück (https://www.delphipraxis.net/111593-runtime-package-gibt-pointer-auf-ein-interface-zurueck.html)

sunny-andy 6. Apr 2008 01:51


Runtime-Package gibt Pointer auf ein Interface zurück
 
Hallo!

Per LoadPackage lade ich ein Runtime-Package und führe dort die Funktion "Boot" aus, welche mir ein Objekt vom Typ "IPluginManager" zurückgeben soll.
IPluginManager ist bei mir ein Interface.

Delphi-Quellcode:
var
  proc: procPointer;
  pModule: HModule;
  dc: TPluginDeliveryClasses;
  pm: IPluginManager;
begin
pModule := LoadPackage('C:\xyz.bpl');

  if pModule = 0 then
    raise EPackageException.Erzeugen(format('Das Package %s wurde nicht gefunden', [TUmgebungsvariablen(TUmgebungsvariablen.NewInstance).DEFAULT_PLUGIN_MANAGER_FILE]));
  try
    @proc := GetProcAddress(pModule, 'Boot');
    if Assigned(proc) then
    begin
      dc := TPluginDeliveryClasses.Erzeugen;
      pm := proc(dc);
      pm.LoadPlugins; <-------- Hier machts Peng!!
    end else
      raise EPackageException.Erzeugen(format('Das Package %s enthält keine korrekt Boot-Methode', [TUmgebungsvariablen(TUmgebungsvariablen.NewInstance).DEFAULT_PLUGIN_MANAGER_FILE]));
Also im Debug-Modus sehe ich, dass pm einen Pointer auf das Interface "IPluginManager" enthält. Wenn ich die Methode LoadPlugins ausführe, gibt es aber eine AccessViolation. Das Objekt wurde aber richtig erstellt, deshalb denke ich, liegt der Fehler darin, dass ich den Pointer falsch behandel, oder?

Ich weiß leider nicht so genau, wie ich das machen muss. Habt ihr einen Tipp?

Delphi-Quellcode:
function Boot(DeliveryClasses: TPluginDeliveryClasses): IPluginManager;
var
  pm: TPluginManager;
begin
  pm := TPluginManager.Erzeugen(DeliveryClasses);
  result := pm;
end;
Dankeschön,
Andy

sx2008 6. Apr 2008 09:04

Re: Runtime-Package gibt Pointer auf ein Interface zurück
 
Ich kann so keinen direkten Fehler in deinem Code erkennen.
Die Boot()-Funktion ist korrekt.
Vielleicht ist der Fehler innerhalb der Interface-Methode .LoadPlugins() zu suchen.
Delphi-Quellcode:
      dc := TPluginDeliveryClasses.Erzeugen;
      pm := proc(dc);
      Assert(Assigned(pm)); // sicherstellen, dass der interface pointer gefüllt ist
      pm.Test;  // einfache Testmethode, die nur über MessageBox einen Text ausgibt
      pm.LoadPlugins; <-------- Hier machts Peng!!
Ich finde dein Plugin-System mit Packages etwas verwirrend; aber das nur nebenbei.
Man kann das mit ActiveX-DLLs viel einfacher und übergreifend für alle Prog.-Sprachen machen.

sunny-andy 6. Apr 2008 11:38

Re: Runtime-Package gibt Pointer auf ein Interface zurück
 
Hallo,
danke für deine Antwort!
Die Assert Methode wirft auch keinen Fehler. Meine Methode "LoadPlugins" ist sozusagen auch eine Testmethode, da dort noch kein Code enthalten ist.
Deshalb kann das nur daran liegen, dass hier
Delphi-Quellcode:
pm := proc(dc);
mit pm irgendwas nicht stimmt. Wenn ich als Rückgabetyp anstatt ein Interface einen elementaren Datentyp wie boolean nehme, kann ich den Rückgabewert ohne Probleme auslesen. Aber mit dem Interface klappt dies hier leider nicht so...

sunny-andy 6. Apr 2008 12:20

Re: Runtime-Package gibt Pointer auf ein Interface zurück
 
Ha! jetzt gehts! Sowelche Momente liebe ich ja :-D

Es war folgendes:
Das PluginManager-Package, welches ich zur Laufzeit geladen habe, soll ja in der Boot-Funktion ein Objekt zurückgeben, welches IPluginManager implementiert.
Dieses Interface ist aber in einem statischen Schnittstellen-Package gelagert.

In dem dynamischen Package (PluginManager) habe ich aus dem "Requires-Ordner" nun die Referenz zu dem Package entfernt, in dem das Interface gespeichert ist und es funktioniert.

Was hat das zu bedeuten? Ich denke, wenn ein Package unter "Requires" aufgelistet ist, werden alle Klassen mit in das aktuelle Package gepackt.

sx2008 6. Apr 2008 19:28

Re: Runtime-Package gibt Pointer auf ein Interface zurück
 
Schwierig aus der Ferne.
Aber wenn du das Interface IPluginManager zweimal definiert haben solltest, dann kommt es zum Problemen, wenn die GUID entweder unterschiedlich ist oder bei einer Deklaration fehlen sollte.
Wenn du sauber arbeiten möchtest, dann brauchst du eine Unit mit Interfacedeklarationen, die von deiner Hauptapplikation und deinem Package eingebunden wird.
Jedes Interface, dass über die "Grenze" transportiert wird braucht zwingend eine GUID.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:56 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