![]() |
Kurioses Problem beim Dynamischen Laden der DLL
Hallo Leute,
ich bin zwar schon länger Mitglied im Forum, aber bis heute immer nur Passiv. Ich habe da so folgendes Problem bei der dynamischen Nutzung einer DLL. Ich habe mir eine DLL geschrieben, um diverse Informationen verschiedener Grafik-Dateien zu erhalten. Diese DLL habe ich dann auch erfolgreich in mein Projekt eingebunden, und, was soll ich als blutiger Hobby-Programmierer (oder einer der es werden möchte) sagen: "Hat super geklappt...". Doch nach viel leserei in Foren, habe ich mich dazu entschlossen, die DLL dynamisch einzubinden. Damit das ganze auch schön dynamisch bleibt, gehe ich sogar hin und lese zuerst die Export-Funktionen der DLL aus. Viel geschreibe, wenig Sinn, eigentlich klappt alles, ich bekomme sogar die richtigen Informationen ausgegeben, aber sobald ich die Informationen haben wird noch vor dem "FreeLibrary" eine Exception ausgelöst mit der Fehlermeldung: "Zugriffsverletzung bei Adresse 0x00000000..." und im Debugger kann ich keine Informationen rausbekommen. Damit ihr euch ein Bild machen könnt, möchte ich euch den Code nicht vorenthalten:
Delphi-Quellcode:
Ach, und übrigens, wenn ich das Programm normal starte (aus dem Explorer) schließt sich die Anwendung an genannter Stelle einfach, ohne ein Exception in Form von Fehlermeldung auszugeben.
unit LoadImgDLL;
interface uses Windows, SysUtils, Classes, ImageHlp; type TImageSize = function(FileName: PChar): integer; stdcall; function GetImgHeight(ImgFile: PChar{; var hSize: Integer}): integer; implementation procedure ListDLLExports(const FileName: string; List: TStrings); type TDWordArray = array [0..$FFFFF] of DWORD; var imageinfo: LoadedImage; pExportDirectory: PImageExportDirectory; dirsize: Cardinal; pDummy: PImageSectionHeader; i: Cardinal; pNameRVAs: ^TDWordArray; Name: string; begin List.Clear; if MapAndLoad(PChar(FileName), nil, @imageinfo, True, True) then begin try pExportDirectory := ImageDirectoryEntryToData(imageinfo.MappedAddress, False, IMAGE_DIRECTORY_ENTRY_EXPORT, dirsize); if (pExportDirectory <> nil) then begin pNameRVAs := ImageRvaToVa(imageinfo.FileHeader, imageinfo.MappedAddress, DWORD(pExportDirectory^.AddressOfNames), pDummy); for i := 0 to pExportDirectory^.NumberOfNames - 1 do begin Name := PChar(ImageRvaToVa(imageinfo.FileHeader, imageinfo.MappedAddress, pNameRVAs^[i], pDummy)); List.Add(Name); end; end; finally UnMapAndLoad(@imageinfo); end; end; end; function GetImgHeight(ImgFile: PChar): integer; var ImgSize: TImageSize; Handle: THandle; List: TStrings; i: Integer; begin result:=0; List := TStringList.Create; try ListDLLExports(PChar(ExtractFilePath(ParamStr(0))+'ImageSize.dll'), List); for i:=0 to List.Count-1 do begin if (pos(LowerCase(Copy(ExtractFileExt(ImgFile), 2, 7)+'h'), LowerCase(List[i]))>0) then begin Handle:=LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+'ImageSize.dll')); if Handle <> 0 then begin @ImgSize := GetProcAddress(Handle, PChar(List[i])); if @ImgSize <> nil then result := ImgSize(ImgFile); //!!!genau hier bekomme ich ein Ergebnis, aber dann ist alles futsch!!! FreeLibrary(Handle); Break; end; end; end; finally List.Free; end; end; Ich hoffe das die Informationen ausreichend sind, und das jemand noch eine Idee hat wo und wie den Fehler suchen/beheben kann. Thanks Stefan |
Re: Kurioses Problem beim Dynamischen Laden der DLL
Das
Delphi-Quellcode:
wid das Problem sein:
procedure ListDLLExports(const FileName: string; List: TStrings);
![]() Blödsinn. Das ist ja der Code vom Programm und nicht von der DLL. Aber überprüf mal deine DLL daraufhin. |
Re: Kurioses Problem beim Dynamischen Laden der DLL
Du kannst auch die DLL debuggen. Dafür trägst du die Anwendung, die die DLL ansteuert, als Hostanwendung im DLL-Projekt ein und drückst dann weiter im DLL-Projekt F9. Dann wird deine Hostanwendung gestartet und in der DLL funktionieren ganz normal Haltepunkte usw., damit solltest du weiter kommen.
Allgemein zu deinem Vorgehen: Wozu eigentlich die Unterscheidung nach Dateityp in deinem Programm? Das kann die DLL doch viel besser. Es reicht ein Export, der dann die korrekte interne Funktion der DLL aufruft. |
Re: Kurioses Problem beim Dynamischen Laden der DLL
Poste bitte mal die genaue Fehlermeldung. Außerdem solltest du deinen Programmablauf überdenken. Du listest allen Ernstes erst die Namen aller exportierten Funktionen in der DLL auf, nur um dann damit GetProcAddress aufzurufen. Das ist zum Schreien ineffizient. Noch schlimmer ist, dass du deine Bibliothek ständig neu lädtst. Das muss doch nicht sein.
|
Re: Kurioses Problem beim Dynamischen Laden der DLL
Das außerdem, aber eigentlich wäre es wohl besser darauf komplett zu verzichten, denn wirklich komplett anpassbar ist das so ja nicht. Nur, wenn man die Auswahl der korrekten Behandlung einer Datei komplett der DLL überlässt, ist eine Änderung immer komplett ohne Änderungen an der Exe machbar.
Und zusätzlich stellt sich das Problem mit der Identifizierung unbekannter neuer Exporte der DLL gar nicht. |
Re: Kurioses Problem beim Dynamischen Laden der DLL
Du solltest auch noch mal die Benennung deiner Funktionen überdenken. ImageSize klingt wie eine Eigenschaft, nicht wie eine Funktion, die einen Wert zurückliefert.
Auch ich muss dich fragen, was die Auflistung aller Exports soll? Kommt eine Funktion hinzu oder fällt weg, musst du eh deinen Code im Programm ändern und anpassen. |
Re: Kurioses Problem beim Dynamischen Laden der DLL
Erstmal vielen Dank für die schnellen Antworten.
Der Hintergrund (Grundgedanke) war, das ich nur die DLL austauschen muss um weitere Graphic-Dateitypen auszuwerten, sozusagen um "neue" Dateitypen dem Programm zur Benutzung zur Verfügung zu stellen. Nichts desto trotz bin ich natürlich über jede Hilfe und Unterweisung dankbar. Ich werde mal die versuchen die DLL die Arbeit übernehmen zu lassen. Aber was mich dennoch interessieren würde, warum wird die Anwendung geschlossen, obwohl das gelieferte Ergebins richtig ist??? Nun ja, ich geb mich mal wieder ran... Gruß Stefan |
Re: Kurioses Problem beim Dynamischen Laden der DLL
Hast du denn in der DLL beim Debuggen einmal geschaut was da beim Aufruf der Funktion passiert?
|
Re: Kurioses Problem beim Dynamischen Laden der DLL
Und zeig uns doch mal den Code der DLL.
|
Re: Kurioses Problem beim Dynamischen Laden der DLL
Zitat:
Für die Kommunikation von DLL und Programm stehen eigentlich genau definierte Schnittstellen zur Verfügung solltest du genau definierte Benutzerschnittstellen festlegen. Die Dynamik musst du selber über dein System erreichen. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:02 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