AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Interface zu dynamischer DLL mit Callback
Thema durchsuchen
Ansicht
Themen-Optionen

Interface zu dynamischer DLL mit Callback

Ein Thema von norwegen60 · begonnen am 4. Jul 2021 · letzter Beitrag vom 5. Jul 2021
Antwort Antwort
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#1

Interface zu dynamischer DLL mit Callback

  Alt 4. Jul 2021, 14:48
Hallo,

ich möchte ein Callback zusammen mit einer dynamisch geladenen DLL behandeln und habe folgenden Test-Code
Delphi-Quellcode:
unit u_IntDll;

interface

uses
  Winapi.Windows;

type
  TCallbackProcedure = procedure(Msg: string); stdcall;
  TSetCallbackProc = procedure(ACallbackProc: TCallbackProcedure); stdcall;
  TEnableDllTimer = procedure(AEnabled: boolean); stdcall;

  TMyMsgEvent = procedure(Msg: string) of object;

  TintDll = class
  private
    FDLLHandle: THandle;
    FOnMyMsg: TMyMsgEvent;

    MyCallbackProc: TSetCallbackProc;
    MyEnableDllTimer: TEnableDllTimer;

    procedure ShowDLLMessage(sMsg:String); stdcall;
  public
    constructor Create;
    destructor Destroy; override;

    property OnMyMsg: TMyMsgEvent read FOnMyMsg write FOnMyMsg;
    procedure Init;
    procedure EnableDllTimer(bValue: boolean);
  end;

procedure ShowDLLMessageExt(sMsg: string); stdcall;

var
  intDll: TintDll;


implementation

procedure ShowDLLMessageExt(sMsg: string); stdcall;
begin
  if assigned(intDll.OnMyMsg) then
    intDll.OnMyMsg(sMsg);
end;

{ TintDll }

constructor TintDll.Create;
begin

end;

destructor TintDll.Destroy;
begin
  FreeLibrary(FDLLHandle);

  inherited;
end;

procedure TintDll.EnableDllTimer(bValue: boolean);
begin
  MyEnableDllTimer(bValue);
end;

procedure TintDll.Init;
begin
  FDLLHandle := LoadLibrary('Callback.dll');
  if FDLLHandle <> 0 then
  begin
    @MyEnableDllTimer := GetProcAddress(FDLLHandle, 'EnableDllTimer');

    @MyCallbackProc := GetProcAddress(FDLLHandle, 'CallbackProc');
    MyCallbackProc(ShowDLLMessageExt);
  end;
end;

procedure TintDll.ShowDLLMessage(sMsg: String);
begin
  if assigned(intDll.OnMyMsg) then
    intDll.OnMyMsg(sMsg);
end;

end.
Weise ich im Init-Part MyCallbackProc(ShowDLLMessageExt); zu, funktioniert das Ganze einwandfrei.
Möchte ich aber alles innerhalb der Klasse behandeln und weise MyCallbackProc(ShowDLLMessage); zu, bekomme ich die Meldung "Inkompatible Typen: Reguläre Procedure und Methodenzeiger"
Mir ist nicht ganz klar, was der Unterschied zwischen dem Handling von ShowDLLMessageExt und ShowDLLMessage ist. Was muss ich machen, dass ich auch den Callback innnerhalb der Klasse behandeln kann?

Grüße
Gerd
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.865 Beiträge
 
Delphi 12 Athens
 
#2

AW: Interface zu dynamischer DLL mit Callback

  Alt 4. Jul 2021, 17:00
Dein Problem ist, dass eine Prozedur und eine Methode trotz gleichem Schlüsselwort
und ähnlicher Semantik doch technisch unterschiedlich sind.

Warum? Bei einer normalen Prozedur Referenz gibt es einen Zeiger. Den auf den Startpunkt
des Codes der Prozedur im Speicher.

Bei einer Methode gibt es zwei Zeiger:
Den auf den Startpunkt des Codes der Methode im Speicher und einen auf die Objektinstanz
zu der die Methode gehört, damit man von dort aus auch an die Daten des Objektes ran kommt.

Grüße
TurboMagic
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#3

AW: Interface zu dynamischer DLL mit Callback

  Alt 4. Jul 2021, 17:22
Du musst das Objekt auch übergeben (vereinfacht) und nimm keinen string:


Delphi-Quellcode:
TCallbackProcedure = procedure(obj: Tobject; Msg: widestring); stdcall;

procedure ShowDLLMessageExt(obj: TObject; sMsg: widestring); stdcall;
begin
  TintDll(obj).OnMyMsg(sMsg);
end;

...

MyCallbackProc(self, @ShowDLLMessageExt)
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#4

AW: Interface zu dynamischer DLL mit Callback

  Alt 4. Jul 2021, 19:37
Das grundsätzliche Problem habe ich verstanden. Ich weiß aber immer noch nicht wie ich es lösen kann. Die Zuweisung auf ShowDLLMessageExt funktioniert jetzt schon korrekt. Ich suche, wie ich auf das klasseneigene ShowDLLMessage verweisen kann.

Delphi-Quellcode:
procedure TintDll.Init;
begin
  FDLLHandle := LoadLibrary('Callback.dll');
  if FDLLHandle <> 0 then
  begin
    @MyEnableDllTimer := GetProcAddress(FDLLHandle, 'EnableDllTimer');

    @MyCallbackProc := GetProcAddress(FDLLHandle, 'CallbackProc');
    MyCallbackProc(ShowDLLMessage);
  end;
end;

procedure TintDll.ShowDLLMessage(sMsg: String);
begin
  if assigned(intDll.OnMyMsg) then
    intDll.OnMyMsg(sMsg);
end;
Hätte jetzt erhofft, dass es mit MyCallbackProc(self, ShowDLLMessage); aber dem ist nicht so.

Standardmässig verwende ich eigentlich Widestring
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.404 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Interface zu dynamischer DLL mit Callback

  Alt 4. Jul 2021, 22:20
Wenn du beide Seiten frei gestalten kannst, kannst du auch schlicht mit Interfaces arbeiten. Wenn du an die DLL z.B. ein Interface IUserDialog übergibst, kann dieses die Prozedur ShowDLLMessage enthalten. Dann kannst du die einfach und ohne Tricks aus der DLL aufrufen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#6

AW: Interface zu dynamischer DLL mit Callback

  Alt 5. Jul 2021, 13:12
Wenn du beide Seiten frei gestalten kannst, kannst du auch schlicht mit Interfaces arbeiten. Wenn du an die DLL z.B. ein Interface IUserDialog übergibst, kann dieses die Prozedur ShowDLLMessage enthalten. Dann kannst du die einfach und ohne Tricks aus der DLL aufrufen.
Ich habe schon mal eine Klasse an eine DLL übergeben, auch wenn hier im Forum davor vielfach gewarnt wird. Läuft aber zuverlässig so lange man sicher stellt, dass bei einer Änderung der Klasse beide Seiten kompiliert werden.

Mit Interfaces habe ich noch nie gearbeitet. Müsste schauen wie groß der Umstellungsaufwand ist. Wenn ich an mein Projekt mit der Klasse denke, da waren die Vereinfachungen enorm.

Trotzdem die Frage: Gibt es eine Möglichkeit MyCallbackProc mit der klasseneigenen Procedure zu verbinden?
  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 17:25 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