![]() |
Problem bei DLL Einbindung...
Ich habe ein paar Probleme mit der Einbindung einer dll in mein Projekt
1. Bei dynamischer Bindung werden alle Parameter ignoriert :cry: (Button1Click) 2. Bei statischer Bindung ist nur ein einziger Aufruf der betr. Funktion möglich :? (Button2Click) 3. Die Dll macht einen OLE-Zugriff, weshalb ein CoInitializeEx(nil, COINIT_MULTITHREADED); in meinem Projekt notwendig wird. Kann man die DLL so verändern, dass es für das aufrufende Programm egal ist was innerhalb der dll abläuft (also kein Aufruf von CoInitialize)? Auch ein CoInitialize innerhalb der dll bringt nichts :? Programmcode
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, imagehlp, ActiveX; function GetMailsEx(KillDuplicates, RealNameEnabled, RealNameSimulated, FromOutlook, FromOpera, FromNetscape, FromLotusNotes, FromEudora, FromPegasus: boolean): PChar; stdcall; external 'B:\Projekte\Komponenten\LocalMail\dll\localmail.dll' name 'GetMails'; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); type TGetMails = function(KillDuplicates, RealNameEnabled, RealNameSimulated, FromOutlook, FromOpera, FromNetscape, FromLotusNotes, FromEudora, FromPegasus: boolean): PChar; var LibHandle: THandle; fGetMails: TGetMails; Antwort: string; begin LibHandle := LoadLibrary('B:\Projekte\Komponenten\LocalMail\dll\localmail.dll'); if LibHandle = 0 then raise Exception.Create('Unable to Load DLL...') else begin try @fGetMails := GetProcAddress(LibHandle, 'GetMails'); if @fGetMails <> nil then begin Antwort := string(fGetMails(True, True, True, True, True, True, True, True, True)); // Invoke the Pr ocedure within the DLL end; except on E: Exception do ShowMessage('Exception error: ' + E.Message); end; end; FreeLibrary(LibHandle); // Free Memory Allocated for the DLL showmessage(Antwort); end; procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage(String(GetMailsEx(True, True, True, True, True, True, True, True, True))); end; procedure TForm1.FormCreate(Sender: TObject); begin CoInitializeEx(nil, COINIT_MULTITHREADED); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin CoUninitialize; end; end. Code der dll:
Delphi-Quellcode:
P.S.: TFr_LocalMail ist eine eigene Komponente, welche bei Einbindng in ein normales Delphi Programm keinerlei Probleme macht...
library LocalMail;
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt- Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL. Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String- Informationen als PChar- oder ShortString-Parameter übergeben. } uses SysUtils, Classes, ActiveX, Fr_LocalMail; {$R *.res} function GetMails(KillDuplicates, RealNameEnabled, RealNameSimulated, FromOutlook, FromOpera, FromNetscape, FromLotusNotes, FromEudora, FromPegasus: boolean): Pchar; export; stdcall; var MyMailList: TFr_LocalMail; begin MyMailList := nil; Result := #0; try MyMailList := TFr_LocalMail.Create(nil); MyMailList.KillDuplicates := KillDuplicates; MyMailList.RealNameEnabled := RealNameEnabled; MyMailList.RealNameSimulated := RealNameSimulated; MyMailList.FromOutlook := FromOutlook; MyMailList.FromOpera := FromOpera; MyMailList.FromNetscape := FromNetscape; MyMailList.FromLotusNotes := FromLotusNotes; MyMailList.FromEudora := FromEudora; MyMailList.FromPegasus := FromPegasus; Result := PChar(MyMailList.Mails.CommaText); finally MyMailList.Free; end; end; exports GetMails name 'GetMails'; begin end. |
Re: Problem bei DLL Einbindung...
Moin FriFra,
bei der dynamischen Einbindung hast Du stdcall vergessen. |
Re: Problem bei DLL Einbindung...
ShareMem wird wahrscheinlich auch gebraucht.
|
Re: Problem bei DLL Einbindung...
:oops: bei der dynamischen Einbindung hat tatsächlich stdcall gefehlt...
ShareMem kann ich mir jetzt auch sparen, da ich jetzt auf Pointer umgestellt habe ;) Ein Problem bleibt jedoch... Ein Parameter meiner Funktion bewirkt, dass die verwendete Komponente kurzzeitig OLE benötigt, d.h. nur wenn dieser Parameter True ist muss ich CoInitialize aufrufen :? . Kann man das Irgendie umgehen? Source der Dll:
Delphi-Quellcode:
Source des aufrufenden Programmes:
library LocalMail;
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt- Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL. Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String- Informationen als PChar- oder ShortString-Parameter übergeben. } uses SysUtils, Classes, ActiveX, Fr_LocalMail; const MAX_RESULT = 4000; {$R *.res} function GetMails(Mails: PChar; KillDuplicates, RealNameEnabled, RealNameSimulated, FromOutlook, FromOpera, FromNetscape, FromLotusNotes, FromEudora, FromPegasus: boolean): Boolean; export; stdcall; var MyMailList: TFr_LocalMail; begin MyMailList := nil; Result := False; try MyMailList := TFr_LocalMail.Create(nil); MyMailList.KillDuplicates := KillDuplicates; MyMailList.RealNameEnabled := RealNameEnabled; MyMailList.RealNameSimulated := RealNameSimulated; MyMailList.FromOutlook := FromOutlook; MyMailList.FromOpera := FromOpera; MyMailList.FromNetscape := FromNetscape; MyMailList.FromLotusNotes := FromLotusNotes; MyMailList.FromEudora := FromEudora; MyMailList.FromPegasus := FromPegasus; StrLCopy(Mails, PCHar(MyMailList.Mails.CommaText), MAX_RESULT); result := True; finally MyMailList.Free; end; end; exports GetMails name 'GetMails'; begin end.
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, imagehlp, ActiveX; function GetMailsEx(Mails: PChar; KillDuplicates, RealNameEnabled, RealNameSimulated, FromOutlook, FromOpera, FromNetscape, FromLotusNotes, FromEudora, FromPegasus: boolean): boolean; stdcall; external 'B:\Projekte\Komponenten\LocalMail\dll\localmail.dll' name 'GetMails'; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; const MAX_RESULT = 4000; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); type TGetMails = function(Mails: PChar; KillDuplicates, RealNameEnabled, RealNameSimulated, FromOutlook, FromOpera, FromNetscape, FromLotusNotes, FromEudora, FromPegasus: boolean): boolean; stdcall; var LibHandle: THandle; fGetMails: TGetMails; Antwort: PChar; begin LibHandle := LoadLibrary('B:\Projekte\Komponenten\LocalMail\dll\localmail.dll'); if LibHandle = 0 then raise Exception.Create('Unable to Load DLL...') else begin try @fGetMails := GetProcAddress(LibHandle, 'GetMails'); if @fGetMails <> nil then begin Antwort := StrAlloc(MAX_RESULT); if fGetMails(Antwort, True, True, True, True, True, True, True, True, True) = True then showmessage(Antwort); end; except on E: Exception do ShowMessage('Exception error: ' + E.Message); end; end; FreeLibrary(LibHandle); // Free Memory Allocated for the DLL end; procedure TForm1.Button2Click(Sender: TObject); var Antwort: PChar; begin Antwort := StrAlloc(MAX_RESULT); if GetMailsEx(Antwort, True, True, True, True, True, True, True, True, True) = True then ShowMessage(Antwort); end; procedure TForm1.FormCreate(Sender: TObject); begin CoInitializeEx(nil, COINIT_MULTITHREADED); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin CoUninitialize; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:42 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