Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Fehler bei FreeLibrary (https://www.delphipraxis.net/103270-fehler-bei-freelibrary.html)

Thanatos81 13. Nov 2007 16:12


Fehler bei FreeLibrary
 
Moin Moin!

Ich hab hier ein kleines Problem beim Benutzen einer DLL. Im FormCreate rufe ich folgendes auf:

Delphi-Quellcode:
DLLHandle := LoadLibrary('OpAgent.dll');
if DLLHandle <> 0 then
begin
  //Funktionen aus der DLL dynamisch laden
  @OPAStart := GetProcAddress(DLLHandle, 'OPAStart');
  @OPAConnect := GetProcAddress(DLLHandle, 'OPAConnect');
  @OPAClose := GetProcAddress(DLLHandle, 'OPAClose');
  @OPAFetch := GetProcAddress(DLLHandle, 'OPAFetch');
  @OPAWrite := GetProcAddress(DLLHandle, 'OPAWrite');
end;
Im FormDestroy
Delphi-Quellcode:
//falls die DLL beim Programmstart geladen wurde, diese wieder freigeben
if DLLHandle <> 0 then
  FreeLibrary(DLLHandle);
Jetzt knallt bei FreeLibrary allerdings. Ich bekommen eine wunderbare Zugriffsverletzung :evil:
Das seltsame ist: Kompiliere ich mit Laufzeitpackages, knallt es nicht. Leider kann ich das Projekt aufgrund von Vorgaben nicht mit Laufzeitpackages ausliefern und der Quelltext der DLL liegt mir auch nicht vor.

Jemand schon einmal ein Ähnliches Phänomen gehabt?

Danke im Voraus!

Bernhard Geyer 13. Nov 2007 16:22

Re: Fehler bei FreeLibrary
 
Wurden auch schön alle Objekte wieder aufgeräumt die angefordert wurden?

Muetze1 13. Nov 2007 16:33

Re: Fehler bei FreeLibrary
 
Werden vllt. die importierten Funktionen zufälligerweise zeitlich in der Nähe der FreeLibrary() aufgerufen?

hoika 13. Nov 2007 16:34

Re: Fehler bei FreeLibrary
 
Hallo,

1. Strings als Parameter verwendet ?
2. knallt es auch, wenn due FreeLibrary direkt nach dem GetProcAddress aufrufst,
als keine Funktionen aufrufst ?
3. debugge doch die Dll.


Heiko

Thanatos81 13. Nov 2007 16:58

Re: Fehler bei FreeLibrary
 
@Bernhard
Das ist eine verdammt gute Frage. Habe mal ein Testprogramm nur mit der DLL und zwei Buttons geschrieben zum Testen:

Delphi-Quellcode:
var
  Form1: TForm1;
  DLLHandle: Integer;

  OPAStart: function: Integer; cdecl;
  OPAConnect: function(ltsap, rtsap, host: PChar; lpHandle: PDWORD; callback:
    PCALLBACK): Integer; cdecl;
  OPAClose: function(handle: DWORD): Integer; cdecl;
  OPAFetch: function(handle: DWORD; lpOperand: PChar; lpBuffer: PVOID;
    BufferSize: DWORD; callback: PCALLBACK): Integer; cdecl;
  OPAWrite: function(handle: DWORD; lpOperand: PChar; lpBuffer: PVOID;
    BufferSize: DWORD; callback: PCALLBACK): Integer; cdecl;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin
  DLLHandle := LoadLibrary('OpAgent.dll');
  if DLLHandle <> 0 then
  begin
    //Funktionen aus der DLL dynamisch laden
    @OPAStart := GetProcAddress(DLLHandle, 'OPAStart');
    @OPAConnect := GetProcAddress(DLLHandle, 'OPAConnect');
    @OPAClose := GetProcAddress(DLLHandle, 'OPAClose');
    @OPAFetch := GetProcAddress(DLLHandle, 'OPAFetch');
    @OPAWrite := GetProcAddress(DLLHandle, 'OPAWrite');

    //OPAStart;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if DLLHandle <> 0 then
  begin
    try
      FreeLibrary(DLLHandle);
    except
      showMessage('2');
    end;
  end;
end;
Nehme ich das "OPAStart" wieder rein, erhalte ich beim FreeLibrary den selben Fehler wie im eigentlichen Programm. Lasse ich es auskommentiert kann ich so oft ich möchte abwechselnd Button1 und Button2 klicken.

Der Rückgabewert von OPStart ist allerdings nur ein ErrorCode, also kein Zeiger auf ein Objekt oder Ähnliches.

Was mich noch wundert: Das try..excpet..end fängt den Fehler nicht ab sondern wird anscheinend vollkommen ignoriert.

@Muetze1 (roter Kasten sei Dank ;-) )
Nein, daran liegt es leider nicht, da könne auch ruhig mehrere Sekunden vergehen.

@hoika (roter Kasten sei Dank ;-) )

1.) ShareMem ist das erste in der uses-Klausel der Projektdatei, aber wie man weiter oben sieht werden nur PChar genutzt, keine Strings.
2.) Nein, siehe oben in diesem Beitrag.
3.) Wie debugge ich eine Fremd-DLL zu der mir kein Quelltext vorliegt? Gibts da irgendwo ein empfehlenswertes Tutorial?

Muetze1 13. Nov 2007 17:09

Re: Fehler bei FreeLibrary
 
Sicher das es cdecl als Aufrufkonvention ist und nicht stdcall o.ä.?

Apollonius 13. Nov 2007 17:11

Re: Fehler bei FreeLibrary
 
Da OPAStart parameterlos ist, kann der Stack eigentlich nicht durch falsche Aufrufkonvention zerschossen werden.

Bernhard Geyer 13. Nov 2007 17:13

Re: Fehler bei FreeLibrary
 
Zitat:

Zitat von Thanatos81
Nehme ich das "OPAStart" wieder rein, erhalte ich beim FreeLibrary den selben Fehler wie im eigentlichen Programm. Lasse ich es auskommentiert kann ich so oft ich möchte abwechselnd Button1 und Button2 klicken.

Wie wäre es mit Aufruf von OPAClose? Wer weis was alles bei OPAStart für Aktionen ausgeführt werden?

Muetze1 13. Nov 2007 18:04

Re: Fehler bei FreeLibrary
 
Zitat:

Zitat von Apollonius
Da OPAStart parameterlos ist, kann der Stack eigentlich nicht durch falsche Aufrufkonvention zerschossen werden.

Da bei CDECL im Gegensatz zu allen anderen Formen der Aufrufer den Stack bereinigt, hatte ich dies vermutet. Schliesslich wusste ich nun nicht aus der Mütze ob der Rückgabewert bei cdecl über Register oder vllt. über Stack zurück gegeben wird...

Thanatos81 14. Nov 2007 08:08

Re: Fehler bei FreeLibrary
 
Nun, die Aufrufkonvention habe ich aus einem Beispielprojekt des Herstellers, indem die DLL fest eingebunden ist. OPAClose ist leider nicht das Gegenstück zu OPAStart, sondern zu OPAConnect. OPAConnect baut eine TCP/IP-Verbindung zu einem bestimmten Gerät auf und OPAClose beendet diese wieder.

Gibt es eine Möglichkeit alle exportierten Methoden einer DLL herauszufinden? Vielleicht gibt es ja ein OPAStop o.Ä. und der Hersteller hat dies nur nicht dokumentiert.
//Edit
Selber ne Möglichkeit gefunden (Danke Assarbad ;-) ) Leider gibts keine Stop-Routine.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 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 by Thomas Breitkreuz