Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem bei DLL Einbindung... (https://www.delphipraxis.net/9877-problem-bei-dll-einbindung.html)

FriFra 6. Okt 2003 23:00


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:
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.
P.S.: TFr_LocalMail ist eine eigene Komponente, welche bei Einbindng in ein normales Delphi Programm keinerlei Probleme macht...

Christian Seehase 6. Okt 2003 23:21

Re: Problem bei DLL Einbindung...
 
Moin FriFra,

bei der dynamischen Einbindung hast Du stdcall vergessen.

Robert Marquardt 7. Okt 2003 06:43

Re: Problem bei DLL Einbindung...
 
ShareMem wird wahrscheinlich auch gebraucht.

FriFra 7. Okt 2003 08:56

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:
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.
Source des aufrufenden Programmes:
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 10:42 Uhr.

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