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.