Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Callback aus von DLL zu EXE in Delphi (https://www.delphipraxis.net/194619-callback-aus-von-dll-zu-exe-delphi.html)

norwegen60 13. Dez 2017 11:34

Delphi-Version: 5

Callback aus von DLL zu EXE in Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich will aus einer DLL beliebige String-Informationen von der DLL zur EXE schicken. Dabei können die Ereignisse durch unterschiedliche Funktiionsaufrufe generiert werden. Eine Schnittstelle könnte z.B. für Log-Informationen sein, die die EXE in die DB scheiben soll.
Ich habe diverse Berichte zu diesem Theme gelesen und zum Schluss auch ein lauffähiges Konstrukt hinbekommen. Jetzt wollte ich mal nachfragen, ob das so alles korrekt ist oder ob noch Fehler enthalten sind. Lauffähig ist das Ganze und Warnungen erzeugt der Compiler auch keine.
Ich habe mal den ganzen Code eingehängt damit die, die auch so was suchen, eine lauffähige Lösung bekommen.

Die DLL
Delphi-Quellcode:
library dllCallBack;
uses
  SysUtils,
  Vcl.ExtCtrls,
  uDefinition;

var
  FCallBackProc: TCallBackProc;

{$R *.res}

// Procedure zum testen der CallBack Funktion
procedure FTimerTimer(Sender: TObject);
begin
  if Assigned(FCallBackProc) then
    FCallBackProc(FormatDateTime('hh:mm:ss.zzz', now));
end;

// CallBack aufruf festlegen
procedure SetCallBackProc(CallBackProc: TCallBackProc); stdcall
begin
  FCallBackProc := CallBackProc; // @FCallBackProc := CallBackProc; geht auch
end;

// Testloop starten
procedure Start; stdcall
var
  i : Integer;
begin
  for i:=1 to 100 do
  begin
    FTimerTimer(nil);
    sleep(200);
  end;
end;

exports
  SetCallBackProc, Start;

begin
end.
Hier ist die Frage ob die Zuweisung in SetCallBackProc über
Delphi-Quellcode:
FCallBackProc := CallBackProc;
oder besser
Delphi-Quellcode:
@FCallBackProc := CallBackProc;
erfolgen muss. Beides funktioniert.

Die gemeinsame Schnittstellendefinition
Delphi-Quellcode:
unit uDefinition;

interface
type
  TCallBackProc = procedure(Command: WideString); stdcall;

implementation

end.
Die EXE
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    meMessage: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
// DLL-Schnittstellen definieren
procedure SetCallBackProc(CallBackProc: TCallBackProc); stdcall external 'dllCallBack.DLL';
procedure Start; stdcall external 'dllCallBack.DLL';

// Callback-Handler
procedure HandleMessage(sMsg:WideString);
begin
  Form1.meMessage.Lines.Add(sMsg);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  // CallBack-Procedure festlegen
  SetCallBackProc(@HandleMessage);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Start;
end;
Danke für eure Feedbacks

Grüße
Gerd

Der schöne Günther 13. Dez 2017 11:47

AW: Callback aus von DLL zu EXE in Delphi
 
Fehlt bei der Implementation von deinem
Delphi-Quellcode:
HandleMessage(..)
nicht noch die
Delphi-Quellcode:
stdcall
-Konvention?

norwegen60 13. Dez 2017 13:43

AW: Callback aus von DLL zu EXE in Delphi
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1388717)
Fehlt bei der Implementation von deinem
Delphi-Quellcode:
HandleMessage(..)
nicht noch die
Delphi-Quellcode:
stdcall
-Konvention?

Stimmt. Das war es was ich noch fragen wollten, denn dort hatte ich auch beide Varianten im Netz gefunden und beide funktionieren. Also mit und ohne
Delphi-Quellcode:
stdcall
. Was ist richtig?

Geht in die gleiche Richtung wie in der DLL die Zuweisung
Delphi-Quellcode:
FCallBackProc := CallBackProc;
oder
Delphi-Quellcode:
@FCallBackProc := CallBackProc;
Beides funktioniert aber was ist richtig?

Zacherl 13. Dez 2017 15:03

AW: Callback aus von DLL zu EXE in Delphi
 
Zitat:

Zitat von norwegen60 (Beitrag 1388738)
Zitat:

Zitat von Der schöne Günther (Beitrag 1388717)
Fehlt bei der Implementation von deinem
Delphi-Quellcode:
HandleMessage(..)
nicht noch die
Delphi-Quellcode:
stdcall
-Konvention?

Stimmt. Das war es was ich noch fragen wollten, denn dort hatte ich auch beide Varianten im Netz gefunden und beide funktionieren. Also mit und ohne
Delphi-Quellcode:
stdcall
. Was ist richtig?

Ist komplett egal, solange du beides Mal die gleiche Calling-Convention verwendest. Man nimmt ganz gerne
Delphi-Quellcode:
stdcall
, wenn Dlls z.b. mit anderen Programmiersprachen kompatibel sein sollen, da Delphis implizite Standard
Delphi-Quellcode:
pascal
-CC nicht überall unterstützt wird.

Zitat:

Zitat von norwegen60 (Beitrag 1388738)
Geht in die gleiche Richtung wie in der DLL die Zuweisung
Delphi-Quellcode:
FCallBackProc := CallBackProc;
oder
Delphi-Quellcode:
@FCallBackProc := CallBackProc;
Beides funktioniert aber was ist richtig?

Ist auch komplett egal bzw. einfach nur Geschmackssache.

Der schöne Günther 13. Dez 2017 16:32

AW: Callback aus von DLL zu EXE in Delphi
 
Also ich sehe dass ich, wenn ich das @ weglasse, in beiden Fällen einen Fehler E2009 "Unterschiede in der Aufrufkonvention" bekomme wenn ich versuche eine Routine ohne stdcall in eine Variable zu stecken die stdcall erwartet. Das ist gut.

Bei der @-Variante nicht.

norwegen60 13. Dez 2017 19:52

AW: Callback aus von DLL zu EXE in Delphi
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1388769)
Also ich sehe dass ich, wenn ich das @ weglasse, in beiden Fällen einen Fehler E2009 "Unterschiede in der Aufrufkonvention" bekomme wenn ich versuche eine Routine ohne stdcall in eine Variable zu stecken die stdcall erwartet. Das ist gut.

Bei der @-Variante nicht.

Ich habe das Projekt mal auf eine VM mit Delphi XE kopiert und dort kompiliert und gestartet.
Delphi-Quellcode:
// CallBack aufruf festlegen
procedure SetCallBackProc(CallBackProc: TCallBackProc); stdcall
begin
  FCallBackProc := CallBackProc; // @FCallBackProc := CallBackProc; geht auch
end;
Ohne @ funktioniert es einwandfrei. Mit @ bekomme ich in XE die Meldung "E2035. Not enough parameter."

Dann habe ich in der EXE
Delphi-Quellcode:
// Callback-Handler
procedure HandleMessage(sMsg:WideString); stdcall;
begin
  Form1.meMessage.Lines.Add(sMsg);
end;
mit und ohne stcall; probiert. Das hat beides ohne Probleme funktioniert

und auch
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  // CallBack-Procedure festlegen
  SetCallBackProc(@HandleMessage); // funktioniert mit und ohne @
end;
funktioniert mit und ohne @

Zacherl 14. Dez 2017 08:27

AW: Callback aus von DLL zu EXE in Delphi
 
Ja, der @ Operator scheint in diesem Falle die Typechecks zu deaktivieren.

Sailor 14. Dez 2017 09:12

AW: Callback aus von DLL zu EXE in Delphi
 
Das Verhalten des @-Operators läßt sich in den Projektoptionen -> Compiling einstellen, zumindest noch in Delphi2010. Ist das jetzt anders?

norwegen60 14. Dez 2017 09:14

AW: Callback aus von DLL zu EXE in Delphi
 
Zitat:

Zitat von Zacherl (Beitrag 1388815)
Ja, der @ Operator scheint in diesem Falle die Typechecks zu deaktivieren.

Das verstehe ich nicht ganz. Durch die Verwendung von TCallBackProc sollten doch alle Aufrufe vom gleichen Typ sein?

himitsu 14. Dez 2017 10:04

AW: Callback aus von DLL zu EXE in Delphi
 
Nicht ganz.
Dank dem @ kann man ohne manuelles Casten auch typlose Pointer zuweisen, wie z.B. von Bei Google suchenGetProcAddress.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:38 Uhr.
Seite 1 von 2  1 2      

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