Einzelnen Beitrag anzeigen

tdeck

Registriert seit: 26. Jun 2006
Ort: Obertshausen
69 Beiträge
 
Delphi 11 Alexandria
 
#1

DLL Dynamisch laden, bei FreeLibrary gibt es einen Fehler

  Alt 26. Jun 2006, 20:10
Hallo,

ich weiss leider keinen Rat mehr, eine passende Lösung habe ich auch nicht gefunden.

Ich schreibe ein OutlookAddin als COM, das eine DLL-Funktion meines Softwareherstellers
nutzen soll, um die ankommenden EMail direkt aus Outlook in die Projektverwaltung zu exportieren.

Das mit dem Addin und mit dem SecureCode für Outlook habe ich mittlerweile gelöst.

Das Problem ist aber, wenn ich die DLL-Funktionen statisch einbinde funktioniert zwar mein
Testprogramm mit den DLL-Funktionen einwandfrei. Aber wenn ich versuche die DLL's statisch in
die ActiveXServer-Lib zu nutzen, sucht mein Programm überall nach den DLL's nur nicht dort wo sie
liegen.

Nach kurzer Rücksprache mit dem Hersteller der DLL, muss das aufrufende Programm im Verzeichnis der
Hauptroutine stehen. Auch das habe ich bereits ohne erfolg probiert.

Nun wollte ich versuchen die DLL-Dynamisch zu laden, hier der CODE:

Delphi-Quellcode:

unit Unit_Test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    cb1: TCheckBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

// Typendeklaraqtion für Dynamisches laden der DLL's

// Fremd-Dokument importieren
  TImportFremdDokument = function( FileToImport, Betreff: PChar; ProjektAuswahl, AdressAuswahl, ShowImportDlg, CopyToFremdDir: Boolean): Boolean; stdcall;

// Adress-Historie öffnen
  TOpenAdrHist = function( AdrNr: PChar): Boolean; stdcall;

// liefert den letzten in der DLL aufgetretener Fehler, PBuf muß auf einen Speicherbereich der Länge BufLen zeigen, hier wird die Meldung abgelegt
  TGetLastPartnerErr = procedure( PBuf: Pointer; BufLen: LongInt ); stdcall;
  TOpenPartner = function( PRec: Pointer ): LongInt; stdcall;
  TClosePartner = procedure; stdcall;

  TPartnerInitRec = packed record // wird bei OpenPartner übergeben (siehe initialization)
    // vvvv diese Werte sind vom Aufrufer zu füllen
    Size : LongInt; // Größe in Byte, wird für Versionierung in der DLL verwendet
    R : LongInt; // Partner-Authentifizierung
    W : LongInt; // Partner-Authentifizierung
    HideExceptions : LongInt; // <> 0 übergeben, wenn die DLL selbst keine Exceptions anzeigen soll
    ShowDebugInfos : LongInt; // <> 0 übergeben, um Inhalt von Record etc. in der DLL angezeigt zu kriegen
    // vvvv diese Werte gibt die DLL bei aufruf von OpenPartner zurück
    Mandant : array[0..100] of Char; // derzeit aktiver Hapak-Mandant
    User : array[0..100] of Char; // derzeit aktiver Hapak-Benutzer
    DLLVersion : array[0..20] of Char; // Version der DLL (nicht Hapak)
    // vvvv Reserve
    Reserve : array[0..255] of Char;
  end;
const
  cDLL = 'check.DLL';

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  PartnerInitRec : TPartnerInitRec; // wird in initialization gefüllt
  ImportFremdDokument : TImportFremdDokument;
  OpenAdrHist : TOpenAdrHist;
  GetLastPartnerErr : TGetLastPartnerErr;
  OpenPartner : TOpenPartner;
  ClosePartner : TClosePartner;
  dllHandle : THandle;

begin

try
 dllHandle := LoadLibrary( cDLL );
  if dllHandle <> 0 then
   begin

// Ziehe die Funktionen aus der DLL
       @OpenPartner := GetProcAddress( dllHandle, 'OpenPartner');
        if @OpenPartner <> NIL then
          OpenPartner(@PartnerInitRec)
        else
          ShowMessage('Fehler OpenPartner');

       @OpenAdrHist := GetProcAddress( dllHandle, 'OpenAdrHist');
        if @OpenAdrHist = NIL then
          ShowMessage('Fehler OpenAdrHist');

       @ClosePartner := GetProcAddress( dllHandle, 'ClosePartner');
        if @ClosePartner = NIL then
          ShowMessage('Fehler ClosePartner');

       @ImportFremdDokument := GetProcAddress( dllHandle, 'ImportFremdDokument');
        if @ImportFremdDokument = NIL then
          ShowMessage('Fehler ImportFremdDokument');

        @GetLastPartnerErr := GetProcAddress( dllHandle, 'GetLastPartnerErr');
        if @GetLastPartnerErr = NIL then
          ShowMessage('Fehler GetLastPartnerErr');

     // hier soll der eigentliche CODE laufen
         if @OpenAdrHist <> NIL then OpenAdrHist( PChar('10203'));

    end
     else
      begin
       ShowMessage('Fehler kann Partner.dll nicht geöffnet!');
        exit;
     end;

finally
  if dllHandle <> 0 then
   begin
    if @ClosePartner <> NIL then ClosePartner;

     @OpenPartner :=NIL; //hier der versuch das ganze evtl. auf NIL zu setzen, ohne Erfolg!
      @OpenAdrHist :=NIL;
       @ClosePartner:=NIL;
        @ImportFremdDokument :=NIL;
         @GetLastPartnerErr :=NIL;

      FreeLibrary( dllHandle ); // <--- hier stürzt es immer ab.
   end;

end; // ENDE Finally..

end;
end.
Sobald die Funktion gestartet wird, klappt alles einfach wunderbar, alle DLL-Funktionen laufen ohne FEHLER.

Aber beim beenden "FreeLibrary(dllHandle)", meldet sich Delphi:

Im Projekt .....PRJ_Test.exe sind zu viele aufeinanderfolgende Exceptions aufgetreten: "Zugriffsverletzung bei 0x00000000: Lesen con Adresse 0x00000000" Prozess wurde angehalten....

Für mich sieht es danach aus, als ob irgendwas noch auf diesen dllHandle zugreift.
Aber alles was ich nutze, ist nach dieser Funktion nicht mehr verwendet (oder habe ich was übersehen?)

Wenn ich die Funktion "FreeLibrary( dllHandle )" ausklammere klappt alles wunderbar, nur wird die DLL nicht mehr freigegeben, deswegen möchte ich das eigentlich nicht machen.

Ich habe hier einfach keinen Lösungsansatz mehr.
Thorsten
bye bye
tdeck
  Mit Zitat antworten Zitat