Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Kurioses Problem beim Dynamischen Laden der DLL (https://www.delphipraxis.net/131978-kurioses-problem-beim-dynamischen-laden-der-dll.html)

Bambuti2000 3. Apr 2009 17:17


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:
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;
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.

Ich hoffe das die Informationen ausreichend sind, und das jemand noch eine Idee hat wo und wie den Fehler suchen/beheben kann.

Thanks
Stefan

Luckie 3. Apr 2009 17:21

Re: Kurioses Problem beim Dynamischen Laden der DLL
 
Das
Delphi-Quellcode:
procedure ListDLLExports(const FileName: string; List: TStrings);
wid das Problem sein: http://www.michael-puff.de/Artikel/StringDLL.shtml Das gilt nicht nur für Strings, sondern auch für jegliche andere Objekte.

Blödsinn. Das ist ja der Code vom Programm und nicht von der DLL. Aber überprüf mal deine DLL daraufhin.

jaenicke 3. Apr 2009 17:23

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.

Apollonius 3. Apr 2009 17:26

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.

jaenicke 3. Apr 2009 17:32

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.

Luckie 3. Apr 2009 17:32

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.

Bambuti2000 3. Apr 2009 17:55

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

jaenicke 3. Apr 2009 23:42

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?

Luckie 3. Apr 2009 23:50

Re: Kurioses Problem beim Dynamischen Laden der DLL
 
Und zeig uns doch mal den Code der DLL.

quendolineDD 4. Apr 2009 11:05

Re: Kurioses Problem beim Dynamischen Laden der DLL
 
Zitat:

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.
Eventuell solltest du dabei dein ganzes Schema einmal überdenken. Wenn dir der Begriff Polymorphie aus der OOP etwas sagt, dürfte es eigentlich schon von meiner Seite aus reichen ;-)
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:

Zitat von Luckie
Kommt eine Funktion hinzu oder fällt weg, musst du eh deinen Code im Programm ändern und anpassen.

Aber ohne Quellcode aus der DLL können wir weiterhin nur unsere :glaskugel: befragen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:34 Uhr.
Seite 1 von 2  1 2   

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