AGB  ·  Datenschutz  ·  Impressum  







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

[DLL]Daten weg nach FreeLibrary

Ein Thema von Profiler · begonnen am 23. Apr 2009 · letzter Beitrag vom 25. Apr 2009
Antwort Antwort
Seite 1 von 2  1 2      
Profiler

Registriert seit: 30. Dez 2006
14 Beiträge
 
#1

[DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 19:43
Hallo,

ich bin mir nicht sicher ob das Thema am besten hierher passt, also schon mal Sorry falls es fehl platziert wurde. Ich beschäftige mich gerade mal wieder mit einer Art Plug-In-System für mein Lüftersteuerungsprogramm PFControl für ThinkPad-Notebooks.
Die jeweiligen DLL's sollen eine Standard-Routine besitzen, dir mir Informationen über sie gibt (Autor, Version, ...). Dabei soll die DLL dynamisch geladen, die Informationen gelesen und im Speicher hinterlegt, und wieder freigegeben werden. In meiner DLL befindet sich also folgende Funktion:

Delphi-Quellcode:
function GetDllInformation: TDllInformation;
begin
  Result.Author := 'Max Mustermann';
  Result.Version := 'v0.2';
  Result.Name := 'Standard-Signale';
end;
Diese Funktion wird exportiert und in meinem Hauptprogramm folgendermaßen aufgerufen:
Delphi-Quellcode:
...
  TFunctionGetDllInformation = function: TDllInformation;
...
    fInfo: TDllInformation;
...
constructor TDll.Create(FileName: String);
var
  Func: TFunctionGetDllInformation;
begin
  Inherited Create;
  fFileName := FileName;
  fDllHandle := 0;
  Load;
  Func := LoadFunction(DLL_GETINFO);
  fInfo := Func;
  Unload; /* Marke 1 */
  fLoaded := False; /* Marke 2 */
end;

procedure TDll.Load;
begin
  fDllHandle := LoadLibrary(PChar(fFileName));
  if fDllHandle = 0 then
    raise Exception.Create('"'+fFileName+'" konnte nicht geladen werden!');
  fLoaded := True;
end;

function TDll.LoadFunction(Name: String): Pointer;
begin
  try
    Result := GetProcAddress(fDllHandle, PChar(Name));
  except
    on E: Exception do
      raise Exception.Create('"'+fFileName+'" ist keine gültige Dll für PFControl: '+E.Message);
  end;
end;

procedure TDll.UnLoad;
begin
  if fLoaded then begin
    FreeLibrary(fDllHandle);
    fLoaded := False;
  end;
end;
Zunächst funktioniert alles perfekt bis /* Marke 1 */ im Konstruktor. Wenn die Prozedur Unload noch nicht aufgerufen wurde, stehen in fInfo (Struktur) die gewünschten Daten. Nachdem Unload aufgerufen wurde (/* Marke 2 */), ist fInfo im Debugger nicht mehr lesbar und die Daten sind weg. Wieso bleiben die Daten beim Freigeben der DLL nicht erhalten bzw. wie kann ich es so lösen ohne die DLL dauerhaft im Speicher zu lassen?

Ich nutze Borland Delphi 7 unter Windows XP.

Gruß
Profiler
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: [DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 19:46
Es handelt sich ja um einen Zeiger auf eine Funktion der Dll. Nach deren Freigabe teigt dieser ins Nirvana
Markus Kinzler
  Mit Zitat antworten Zitat
Profiler

Registriert seit: 30. Dez 2006
14 Beiträge
 
#3

Re: [DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 20:57
Naja dass der Zeiger auf die Funktion futsch geht ist ja klar, aber warum gehen die Daten von fInfo verloren? Die Variable hat doch nichts mit der DLL zu tun oder?
  Mit Zitat antworten Zitat
Benutzerbild von Dunkel
Dunkel

Registriert seit: 26. Mär 2007
Ort: Klingenstadt
541 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: [DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 21:00
Weil fInfo ebenfalls nur ein Zeiger ist.
Du musst die Daten, welche Du aus der DLL bekommst, schon in lokale Variablen speichern. Oder, eigentlich besser und auch der Standard von Windows, Du übergibst der DLL einen, im Hauptprogramm alloizierten Speicherbereich, in welchen die DLL die Informationen schreiben kann. Dieser Bereich überlebt auch die DLL.
Es ist zu wahr um schön zu sein...
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: [DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 21:03
TDllInformation scheint aber ein Record zu sein; dann ist das nicht zu erklären. Hast du ShareMem eingebunden?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

Re: [DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 21:22
fLoaded kannst'e eigentlich weglassen ... fDllHandle<>0 brächte das selbe Ergebnis
mußt nur das Freigeben noch anpassen
Delphi-Quellcode:
procedure TDll.UnLoad;
begin
  {if fDllHandle <> nil then} FreeLibrary(fDllHandle);
  fDllHandle := nil;
end;
und wo sollte bei LoadFunction die Exception entstehen?
Delphi-Quellcode:
function TDll.LoadFunction(Name: String): Pointer;
begin
  Result := GetProcAddress(fDllHandle, PChar(Name));
  if Result = nil then
    raise Exception.CreateFmt('"%s" ist keine gültige Dll für PFControl', [fFileName]);
end;
$2B or not $2B
  Mit Zitat antworten Zitat
Profiler

Registriert seit: 30. Dez 2006
14 Beiträge
 
#7

Re: [DLL]Daten weg nach FreeLibrary

  Alt 23. Apr 2009, 23:16
Zitat von Apollonius:
TDllInformation scheint aber ein Record zu sein; dann ist das nicht zu erklären. Hast du ShareMem eingebunden?
Ja das ist ein Record, ich weiss grad nicht was mit ShareMem gemeint ist, ich beles mich morgen mal.

@himitsu
Ja das fLoaded hab ich nur der Bequemlichkeit halber eingeführt, was dann über ein Property Loaded: Boolean von der Klasse abgefragt werden kann, aber eigentlich brauch ich das nicht, da das Laden und Freigeben in der Klasse vor und nach einem Prozeduraufruf gesichert werden soll.

Bei der Exception hast du Recht, aber ich möchte erstmal kein Fenster zeigen. Das wird dann von Application.OnException in ein Memo geschrieben bzw. beim Funktionsaufruf in einer höheren Klasse mit abgefangen.

Delphi-Quellcode:
function TDll.LoadFunction(Name: String): Pointer;
begin
  Result := GetProcAddress(fDllHandle, PChar(Name));
  if not Assigned(Result) then
    raise Exception.Create('"'+fFileName+'" ist keine gültige Dll für PFControl: '+Name+' nicht gefunden.');
end;
Aber das sind ja nur "Schönheitsfehler" und es löst leider mein eigentliches Problem noch nicht.

Gruß
Profiler
  Mit Zitat antworten Zitat
Blup

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

Re: [DLL]Daten weg nach FreeLibrary

  Alt 24. Apr 2009, 09:18
'Max Mustermann' ist eine String-Konstante, die fest im Speicherbereich der DLL abgelegt ist.

Result.Author := 'Max Mustermann';

Author ist vom Type String, Stringvariablen sind in Wirklichkeit Zeiger auf einen String.
Der Zeiger Author verweist auf den Speicher, in dem die String-Konstante liegt.

Unload;

Der Zeiger Author verweist auf eine Speicheradresse, die nicht mehr von der DLL belegt wird.


Eine mögliche Lösung:
Delphi-Quellcode:
fInfo.Author := Copy(fInfo.Author);
fInfo.Version := Copy(fInfo.Version);
fInfo.Name := Copy(fInfo.Name);
Unload;
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: [DLL]Daten weg nach FreeLibrary

  Alt 24. Apr 2009, 16:42
Zumindest in den späteren Delphi-Versionen werden von String-Konstanten immer Kopien erstellt. Ich weiß allerdings nicht, wie lange das schon so geht. Es ist allerdings klar, dass es bei Strings Probleme mit dem Speichermanager gibt.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Profiler

Registriert seit: 30. Dez 2006
14 Beiträge
 
#10

Re: [DLL]Daten weg nach FreeLibrary

  Alt 25. Apr 2009, 22:48
Hallo,

das mit dem Copy hat mir immer InvalidPointerOperation geworfen.
Ich hab es jetzt aber folgendermaßen gelöst:
Delphi-Quellcode:
type
  PDllInformation = ^TDllInformation;
  TDllInformation = record
    Author: array[0..19] of Char;
    Version: array[0..9] of Char;
    Name: array[0..19] of Char;
  end;
In der Struktur waren vorher Strings deklariert, welche ich zu array of Char geändert habe.
In der DLL steht nun:
Delphi-Quellcode:
procedure GetDllInformation(pInfo: PDllInformation);
begin
  pInfo^.Author := DLL_AUTHOR;
  pInfo^.Version := DLL_VERSION;
  pInfo^.Name := DLL_NAME;
end;
... und der Zugriff erfolgt so:
Delphi-Quellcode:
constructor TDll.Create(FileName: String);
var
  Func: TFunctionGetDllInformation;
begin
  Inherited Create;
  fFileName := FileName;
  fDllHandle := 0;
  Load;
  Func := LoadFunction(DLL_GETINFO);
  Func(fInfo);
  Unload;
end;
Vielen Dank für eure Hilfe.

Gruß
Profiler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 14:40 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