AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem bei DLL Einbindung...

Ein Thema von FriFra · begonnen am 7. Okt 2003 · letzter Beitrag vom 7. Okt 2003
Antwort Antwort
Benutzerbild von FriFra
FriFra

Registriert seit: 19. Apr 2003
1.291 Beiträge
 
Delphi 2005 Professional
 
#1

Problem bei DLL Einbindung...

  Alt 7. Okt 2003, 00:00
Ich habe ein paar Probleme mit der Einbindung einer dll in mein Projekt

1. Bei dynamischer Bindung werden alle Parameter ignoriert (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.dllname '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...
Elektronische Bauelemente funktionieren mit Rauch. Kommt der Rauch raus, geht das Bauteil nicht mehr.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Problem bei DLL Einbindung...

  Alt 7. Okt 2003, 00:21
Moin FriFra,

bei der dynamischen Einbindung hast Du stdcall vergessen.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#3

Re: Problem bei DLL Einbindung...

  Alt 7. Okt 2003, 07:43
ShareMem wird wahrscheinlich auch gebraucht.
  Mit Zitat antworten Zitat
Benutzerbild von FriFra
FriFra

Registriert seit: 19. Apr 2003
1.291 Beiträge
 
Delphi 2005 Professional
 
#4

Re: Problem bei DLL Einbindung...

  Alt 7. Okt 2003, 09:56
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.dllname '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.
Elektronische Bauelemente funktionieren mit Rauch. Kommt der Rauch raus, geht das Bauteil nicht mehr.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:01 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