AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?
Thema durchsuchen
Ansicht
Themen-Optionen

Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

Ein Thema von DeddyH · begonnen am 24. Aug 2015 · letzter Beitrag vom 25. Aug 2015
Antwort Antwort
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.667 Beiträge
 
Delphi 12 Athens
 
#1

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 24. Aug 2015, 16:00
Hab ich gemacht, die Reihenfolge stimmt: zuerst werden die DLL-Objekte freigegeben, danach käme der FreeLibrary-Aufruf. Mittlerweile ist es genau andersherum als eingangs geschildert: wenn ein neuer DLL-Name zugewiesen wird, klappt ein Nullen des alten Objektes mit anschließendem FreeLibrary einwandfrei, nur im Destruktor nicht mehr. Das alles aber nur im echten Projekt, das Referenzbeispiel funktioniert ohne Murren.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.667 Beiträge
 
Delphi 12 Athens
 
#2

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 24. Aug 2015, 19:33
So, zu Hause nochmal unter XE7 nachgebaut und schon den ersten Fehler gefunden (Verwendung von string statt Widestring). Aber auch hier klappt es nur, wenn ich das FreeLibrary auskommentiere. Ich habe den Verdacht, dass ich eine ganz entscheidende Kleinigkeit vergessen habe (das ist zugegebenermaßen mein allererster Versuch in dieser Richtung). Ich hänge meine Demo mal an, jemand mit mehr Erfahrung auf dem Gebiet sieht das evtl. sofort.
Angehängte Dateien
Dateityp: zip Demo.zip (11,7 KB, 9x aufgerufen)
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#3

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 25. Aug 2015, 00:59
Delphi-Quellcode:
procedure TfrmMain.btnLoadClick(Sender: TObject);
type
  TLoadProc = procedure(out Person: IPerson); stdcall;
var
  DLLHandle: NativeUInt;
  PersonProc: TLoadProc;
  Person: IPerson;
  Item: TListItem;
begin
// ...
              while not Person.Eof do
                begin
                  Item := lvChildren.Items.Add;
                  Item.Caption := Person.Child.Name;
                  Item.SubItems.Add(DateToStr(Person.Child.Birthdate));
                  Person.Next;
// ...
    finally
      Person := nil;
      FreeLibrary(DLLHandle);
    end;
end;

Das Problem ist folgendes:
Person.Child liefert ein Interface (IChild). Das wird hier aber nicht in einer lokalen Variable gespeichert, sondern es wird gleich auf eine Eigenschaft zugegriffen (Name, Birthdate). Damit die automatische Referenzzählung funktioniert, muss Delphi aber trotzdem jede Interface-Instanz in einer unsichtbaren lokalen Variable speichern (hier also 2x IChild), die dann am Ende der Subroutine in einem impliziten "finally" Block freigegeben werden.
FreeLibrary wird aber vorher ausgeführt, d.h. es wird auf Ressourcen zugegriffen, die nicht mehr verfügbar sind. Daher die Zugriffsverletzung.

Lösung: Person.Child explizit in einer Variable speichern und die Referenz ebenfalls vor FreeLibrary freigeben.

Delphi-Quellcode:
procedure TfrmMain.btnLoadClick(Sender: TObject);
type
  TLoadProc = procedure(out Person: IPerson); stdcall;
var
  DLLHandle: NativeUInt;
  PersonProc: TLoadProc;
  Person: IPerson;
  Child: IChild;
  Item: TListItem;
begin
// ...
              while not Person.Eof do
                begin
                  Item := lvChildren.Items.Add;
                  Child := Person.Child;
                  Item.Caption := Child.Name;
                  Item.SubItems.Add(DateToStr(Child.Birthdate));
                  Person.Next;
// ...
    finally
      Person := nil;
      Child := nil;
      FreeLibrary(DLLHandle);
    end;
end;

Falls die DLL übrigens erkennen soll, wann sie geladen oder freigegeben wird, dann geht das ungefähr so.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.667 Beiträge
 
Delphi 12 Athens
 
#4

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 25. Aug 2015, 07:34
Das war die entscheidende Kleinigkeit, von der ich gesprochen hatte. Danke Dir herzlich
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.494 Beiträge
 
Delphi 12 Athens
 
#5

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 25. Aug 2015, 12:43
Für ein Plugin-DLL scheint es mir flexibel, wenn diese selbst die von ihr bereitgestellten Interfaces bei der Anwendung registriert.
Dazu wird dem Plugin ein Interface zum Anwendungskern übergeben, bei dem beliebige Interfaces registriert und abgefragt werden können.

Beispiel könnte ein Exportdateiformat sein. Davon kann es mehrere geben, für den Anwendungsfall ist es egal welche davon in der Anwendung oder in einem Plugin realisiert sind.
Der Dateiexport fragt alle registrierten Formate beim Anwendungskern ab, bietet diese dem Anwender an und erzeugt die Datei im gewählten Format.
Sollte dieses Dateiformat die Namen von Artikelgruppen benötigen, kann es dafür vom Anwendungskern ein Interface abfragen, das eine entsprechende Liste bereitstellt.
Das Dateiformat kann in der Plugin-Dll realisiert sein und die Schnittstelle mit den Artikelgruppen in der Anwendung.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 25. Aug 2015, 12:49
Also in ungefähr so
Delphi-Quellcode:
IPlugin = interface
  ['{GUID}']
end;

IPluginHost = interface
  ['{GUID}']
  procedure RegisterPlugin( const Aplugin : IPlugin );
end;
Jede Plugin-DLL bietet eine Methode zum Abrufen an:
Delphi-Quellcode:
procedure QueryPlugin( const Host : IPluginHost ); stdcall;
begin
  Host.RegisterPlugin( TFooPlugin.Create );
  Host.RegisterPlugin( TBarPlugin.Create );
  ...
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.667 Beiträge
 
Delphi 12 Athens
 
#7

AW: Interface aus DLL mit dynamischer Bindung - wann FreeLibrary aufrufen?

  Alt 25. Aug 2015, 15:20
Danke für die Denkarbeit, aber in diese Richtung geht es nicht (es gibt nur ein Interface, und jede DLL gibt exakt dieses zurück). Ich muss zugeben, dass der Begriff PlugIn in der Problemstellung etwas irreführend war.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  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 20:03 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