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, 14:51
Ich bau mal ein Beispiel.
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, 15:15
War ja klar: im Beispiel funktioniert alles , der Fehler muss also an einer anderen Stelle liegen. Ich forsche mal weiter.
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 Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

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

  Alt 24. Aug 2015, 15:38
Du könntest meine Theorie relativ einfach testen, indem du im Destructor deiner Objekte (die aus der DLL) mal eine MessageBox einbaust. Dann ersetzt du das FreeLibrary durch eine weitere MessageBox.

Erscheint jetzt die FreeLibrary Message vor der Message aus dem Destructor, weißt du, dass irgendwo noch Objektinstanzen existieren, die vor dem FreeLibrary nicht freigegeben werden.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  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 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
 
#5

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
 
#6

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
 
#7

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
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 15:56 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