Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Event aus DLL für HotSpot Nutzen (https://www.delphipraxis.net/201107-event-aus-dll-fuer-hotspot-nutzen.html)

Johnny123 24. Jun 2019 11:26

Event aus DLL für HotSpot Nutzen
 
Mahlzeit ich bin neu hier und auch neu bei Delphi

Ich habe folgendes vor und zwar will ich ein Callback für meinen HotSpot einrichten
Bzw ich habe eine Event Procedure in einer DLL dieses Event soll reagieren wenn ich meinen hotSPot auf meinem Gerät drücke!
Quasi also wie ein button allerdings krieg ich es nicht hin das Event auf den button zu Legen!
Dies soll wohlbemerkt alles in einer klasse Verwirklicht werden

Irgendwelche Tipps ?

MfG Johnny

mkinzler 24. Jun 2019 11:27

AW: Event aus DLL für HotSpot Nutzen
 
Was meinst Du mit HotSpot?

Johnny123 24. Jun 2019 11:29

AW: Event aus DLL für HotSpot Nutzen
 
schlichtweg ein Button auf meinem Gerät der hotSpot genannt wird

peterbelow 24. Jun 2019 11:53

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1435233)
Mahlzeit ich bin neu hier und auch neu bei Delphi

Ich habe folgendes vor und zwar will ich ein Callback für meinen HotSpot einrichten
Bzw ich habe eine Event Procedure in einer DLL dieses Event soll reagieren wenn ich meinen hotSPot auf meinem Gerät drücke!
Quasi also wie ein button allerdings krieg ich es nicht hin das Event auf den button zu Legen!
Dies soll wohlbemerkt alles in einer klasse Verwirklicht werden

Irgendwelche Tipps ?

MfG Johnny

Was exportierst Du denn aus der DLL? Kode bitte, zumindest die Deklaration der exportierten Funktion.

Ein Event handler in Delphi muss eine Methode eines Objektes sein, oft ein TNotifyevent, also vom Typ

Delphi-Quellcode:
 procedure (sender: TObject) of Object;
Das "of Object" impliziert, das es sich um eine Methode eines Objektes handeln muss. Das Äquivalent einer standalone procedure mit der gleichen Signatur wäre

Delphi-Quellcode:
  procedure (self: TObject; sender: TObject); // register calling convention!
self ist dabei die Addresse des Objektes, zu dem die Methode gehört, oder der Klasse selbst, bei einer class procedure.

Eine Methode kann man nicht direkt aus einer DLL exportieren, eine Prozedur mit der äquivalenten Signatur aber schon. Um die als Event handler verwenden zu können bedarf es aber eines Tricks. Es gibt einen Typ in Delphi, der eine Methode repräsentiert: TMethod.

Damit kann man einen Tnotifyevent quasi on the fly erzeugen:

Delphi-Quellcode:
var
  M: TMethod;
begin
  M.data := nil;
  M.code := GetProcaddress(dllhandle, NameDerExportiertenProzedur);
  hotspotbutton.OnClick := TNotifyEvent(M);

Der hier verwendete Wert für M.Data wird als Self-Parameter an die Prozedur übergeben. Die Prozedur in der DLL kann den Aufruf dann an eine Methode eines internen Objektes weiterleiten.

Johnny123 24. Jun 2019 12:01

AW: Event aus DLL für HotSpot Nutzen
 
Also bisher habe ich Folgendes versucht

Code:
unit PadKlasse;

interface

uses Winapi.Windows, Classes;

Type
  TSTSensorHotSpotPressed = Procedure(nHotSpotID:integer)Of Object;

  TStPad = class

    constructor create;
    destructor destroy;
private
    FOnSensorHotSpotPressed:TSTSensorHotSpotPressed;
Procedure SensorHotSpotPressed(nHotSpotID : Integer);
procedure STSensorHotSpotPressed_stdcall(nHotSpotId: Smallint);register; // Das ist das Event das ich von der DLL kriege
external 'STPadLib.dll';
Procedure TStPad.SensorHotSpotPressed(nHotSpotID : Integer);
begin
    //

end;
Allerdings funktioniert das so nicht ganz

hoffe das is das was du brauchst !

peterbelow 24. Jun 2019 13:39

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1435241)
Also bisher habe ich Folgendes versucht

Code:
unit PadKlasse;

interface

uses Winapi.Windows, Classes;

Type
  TSTSensorHotSpotPressed = Procedure(nHotSpotID:integer)Of Object;

  TStPad = class

    constructor create;
    destructor destroy;
private
    FOnSensorHotSpotPressed:TSTSensorHotSpotPressed;
Procedure SensorHotSpotPressed(nHotSpotID : Integer);
procedure STSensorHotSpotPressed_stdcall(nHotSpotId: Smallint);register; // Das ist das Event das ich von der DLL kriege
external 'STPadLib.dll';
Procedure TStPad.SensorHotSpotPressed(nHotSpotID : Integer);
begin
    //

end;

Du kannst keine Methode einer Klasse als external deklarieren, das geht nur mit normalen Prozeduren.


Ich versteh auch das Design nicht, was vermutlich teilweise an deiner irreführenden Verwendung von "event" liegt :wink:. Eine DLL exportiert keine Events, sie exportiert Funktionen oder Prozeduren, die von der Anwendung aufgerufen werden sollen, d.h. die Aktion beginnt in der Anwendung (Benutzer drückt button), wird von der Anwendung erkannt (OnClick event des buttons) und die ruft dann eventuell eine von der DLL exportierte Funktion/Prozedur auf, damit die DLL noch irgendwas macht. Danach kehrt der Programmfluss wieder in die Anwendung zurück.

Diese Verwendung von DLLs ist der häufigste Fall, der Aufruf der DLL ist synchron, d.h. kehrt erst zur Anwendung zurück, wenn die DLL ihren Teil erledigt hat. Es gibt auch eine asynchrone Variante, aber die ist ganz anders aufgebaut.

In diesem Fall ruft die Anwendung eine exportierte Funktion auf um einen sog. Callback zu installieren. Das ist eine Funktion der Hostanwendung, die die DLL aufrufen soll, wenn sie etwas an die Hostanwendung übermitteln will. Die Frage ist dann von welchem Punkt im Programmfluß aus dieser Aufruf erfolgen soll. Eine DLL führt nur dann Kode unabhängig von der Hostanwendung aus, wenn sie dafür einen sekundären Thread angelegt hat, ansonsten führt sie nur Kode als Reaktion auf einen Funktionsaufruf der Hostanwendung aus. In diesem kann sie aber durchaus einen vorher installierten Callback aufrufen, z. B. um die Hostanwendung über den Fortschritt der Arbeit zu informieren.

Du hast uns ja bisher so ziemlich nichts über deine Anwendung verraten. Wenn deine TStPad-Klasse im Wesentlichen die externe DLL vom Rest der Anwendung verbergen soll würde das in etwa so funktionieren:

Deine Anwendung hat einen Button mit einem normal in der IDE erzeugten Handler für den OnClick event. Der Eventhandler ruft eine public-Methode einer Instanz deiner TStPad-Klasse auf, diese Methode ruft dann die von der DLL exportierte Funktion auf.

Delphi-Quellcode:
unit PadKlasse;

interface

uses Winapi.Windows, Classes;

Type
  TStPad = class
  public
    constructor create;
    destructor destroy;
    // die wird von button.onclick aufgerufen
    Procedure SensorHotSpotPressed(nHotSpotID : Integer);
  end;

implementation

procedure STSensorHotSpotPressed_stdcall(nHotSpotId: Smallint);stdcall;
external 'STPadLib.dll';

Procedure TStPad.SensorHotSpotPressed(nHotSpotID : Integer);
begin
   STSensorHotSpotPressed_stdcall(nHotspotID);
end;

Johnny123 24. Jun 2019 13:49

AW: Event aus DLL für HotSpot Nutzen
 
Ich kann dir gerne mal die ganze Unit per PN Schicken

Vllt bringt das dan mehr

peterbelow 24. Jun 2019 17:37

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1435255)
Ich kann dir gerne mal die ganze Unit per PN Schicken

Vllt bringt das dan mehr

Glaube ich nicht, sorry. Die Unit nützt nichts wenn Du nicht verrätst, was Du da eigentlich erreichen willst, was die Anwendung tun soll, wo die Dll herkommt und was ihre Funktion ist. Bisher ist noch nicht mal klar, um was für eine Platform es geht und welches Framework (Vcl, fmx) da im Spiel ist. No data, no solution, sorry.

Johnny123 27. Jun 2019 10:19

AW: Event aus DLL für HotSpot Nutzen
 
ok Also ich programmiere in Delphi Xe7
So was das Programm machen soll ...

Es geht um ein Signpad auf diesem sind Buttons die HotSpots genannt werden
und sobald ich einen der buttons Drücke soll dieses Ereignis aus der DLL die zum Signpad gehört aktiviert werden
Framework is VCL

Jeder Hotspot hat seine eigene ID als beispiel wenn ich Den Cancel Hotspot drücke soll die verbindung zum Signpad geschlossen werden

Hoffe das konnte dir jetzt helfen

peterbelow 27. Jun 2019 10:44

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1435465)
ok Also ich programmiere in Delphi Xe7
So was das Programm machen soll ...

Es geht um ein Signpad auf diesem sind Buttons die HotSpots genannt werden
und sobald ich einen der buttons Drücke soll dieses Ereignis aus der DLL die zum Signpad gehört aktiviert werden
Framework is VCL

Jeder Hotspot hat seine eigene ID als beispiel wenn ich Den Cancel Hotspot drücke soll die verbindung zum Signpad geschlossen werden

Hoffe das konnte dir jetzt helfen

Das heist, Du erwartest eine Reaktion der DLL wenn der Benutzer einen Hotspot auf dem Signpad drückt.

Das sieht nach dem asynchronen Scenario aus. Was ist das für eine DLL? Ist es eine COM/ActiveX Library, ein .NET assembly, oder hat sie eine Sammlung von exportierten Funktionen? Ist da irgend eine Datei dabei, die das Interface der DLL beschreibt, ein C-Headerfile, eine type library, Dokumentation, Beispiele zur Anwendung?

Johnny123 27. Jun 2019 11:16

AW: Event aus DLL für HotSpot Nutzen
 
Ja richtig genau Soll halt bei Cancel die verbindung schließen bei Okay auf Unterschrift wechseln etc

Es gibt eine C-Header Datei und eine Dokumentation zu der DLL
Hab noch diverse andere Funktionen aus DLL exportiert die funktionieren soweit auch super

nur mit dem Ereignis hab ich halt ein Problem

peterbelow 27. Jun 2019 11:43

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1435479)
Ja richtig genau Soll halt bei Cancel die verbindung schließen bei Okay auf Unterschrift wechseln etc

Es gibt eine C-Header Datei und eine Dokumentation zu der DLL
Hab noch diverse andere Funktionen aus DLL exportiert die funktionieren soweit auch super

nur mit dem Ereignis hab ich halt ein Problem

Ich müßte die Header-Datei sehen um Dir da weiterhelfen zu können. Kannst Du die in ein zip-Archiv packen und als Anhang an deine Antwort hängen?

Johnny123 28. Jun 2019 09:40

AW: Event aus DLL für HotSpot Nutzen
 
https://workupload.com/file/fDLMb9fH

Hier einmal die Header Datei als Zip
weiß nicht ob man die auch direkt hier einfügen kann

peterbelow 28. Jun 2019 14:31

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1435537)
https://workupload.com/file/fDLMb9fH

Hier einmal die Header Datei als Zip
weiß nicht ob man die auch direkt hier einfügen kann

Man kann Dateianhänge an Forum-Posts anhängen. Wenn Du den POst schreibst ist unter dem Eingabefenster eine Sektion "zusätzliche Einstellungen" und dortselbst findet sich ein "Anhänge verwalten"-Knopf, der einen zu einer Seite bringt, wo man eine Datei ins Forum laden kann.

Anyway, nachdem ich erstmal die Übelkeit überwunden hatte, die mich beim Lesen von C-Kode immer befällt :wink: sieht es so aus, als wenn die DLL wirklich einen asynchronen Benachrichtigungsmechanismus unterstützt.

Code:
// callback typedef
typedef VOID (*CBPTR)(LONG nEvent, LPVOID pData, LONG nDataSize, LPVOID pCustomPar);
Das entspricht der Delphi-Deklaration

Delphi-Quellcode:
type
  TStPadCallback = procedure (nEvent: Longint; pData: Pointer; nDatasize: Longint;
    pCustomPar: pointer); cdecl;
Installiert wird ein solcher callback offenbar mit Hilfe einer der beiden exportierten Funktionen

Code:
extern "C" STPADLIB_API VOID STControlSetCallback(CBPTR pCallback, LPVOID pCustomPar);
extern "C" STPADLIB_API VOID __stdcall STControlSetCallback_stdcall(CBPTR pCallback, LPVOID pCustomPar);
Die unterscheiden sich nur in der calling convention und so wie der Header aussieht ist die stdcall-Variante nur in der 32-Bit DLL verfügbar. Beide sind aus Delphi verwendbar.

Deine Klasse sollte dann etwa so aussehen:

Delphi-Quellcode:

Type
  TStPad = class
  private
    procedure InstallCallback;
    procedure UninstallCallback;
  public
    constructor create;
    destructor destroy; override;
    procedure SensorHotSpotPressed(nHotSpotID : Integer);
  end;

// in implementation section
type
  TStPadCallback = procedure (nEvent: Longint; pData: Pointer; nDatasize: Longint;
    pCustomPar: pointer); cdecl;

procedure STControlSetCallback(pCallback: TStPadCallback; pCustomPar: pointer); cdecl;
  external 'STPadLib.dll';
procedure STControlSetCallback_stdcall(pCallback: TStPadCallback; pCustomPar: pointer);
  stdcall; external 'STPadLib.dll';


const
// callback event IDs
  STPAD_CALLBACK_DISCONNECT = 0;
  STPAD_CALLBACK_HOTSPOT = 1;
  STPAD_CALLBACK_TIMEOUT = 2;
  STPAD_CALLBACK_SCROLL = 3;
  STPAD_CALLBACK_SIGNATURE = 4;

procedure CallbackStub (nEvent: Longint; pData: Pointer; nDatasize: Longint;
    pCustomPar: pointer); cdecl;
var
  LHotspotID: integer;
begin
  if nEvent = STPAD_CALLBACK_HOTSPOT then
    if Assigned(pData) and (nDatasize = sizeof(integer)) then begin
      LHotspotID := pInteger(pData)^;
      if Assigned(pCustomPar) then
        TStPad(pCustomPar).SensorHotSpotPressed(LHotspotID);
    end;
end;


{ TStPad }

constructor TStPad.create;
begin
  inherited;
  InstallCallback;
end;

destructor TStPad.destroy;
begin
  UninstallCallback;
end;

procedure TStPad.InstallCallback;
begin
  STControlSetCallback(CallbackStub, Self);
end;

procedure TStPad.SensorHotSpotPressed(nHotSpotID: Integer);
begin

end;

procedure TStPad.UninstallCallback;
begin
  STControlSetCallback(nil, Self);
end;
Du mußt mal die Dokumentation checken um zu verifizieren, wie der Callback die ID des Hotspots übergeben bekommt, da konnte ich natürlich nur spekulieren.

Johnny123 2. Jul 2019 15:14

AW: Event aus DLL für HotSpot Nutzen
 
Sobald ich zeit habe werde ich es mal austesten
und melde mich dan wieder

Johnny123 16. Jul 2019 09:12

AW: Event aus DLL für HotSpot Nutzen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo peterbelow

also habe es soweit eingebaut nur Kackt jetzt alles ab sobald ich den Hotspot drücke und kriege folgende fehlermeldung
und er öffnet in Delphi das CPU fenster
hab ich als Anhang mal screens von rein gesetzt

hoika 16. Jul 2019 09:15

AW: Event aus DLL für HotSpot Nutzen
 
Hallo,
und wo genau, an welcher Stelle des Quellcodes ?

peterbelow 16. Jul 2019 09:21

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1436826)
Hallo peterbelow

also habe es soweit eingebaut nur Kackt jetzt alles ab sobald ich den Hotspot drücke und kriege folgende fehlermeldung
und er öffnet in Delphi das CPU fenster
hab ich als Anhang mal screens von rein gesetzt

Sieht so aus als wenn die DLL intern auf einen Fehler läuft. Wenn Du einen breakpoint auf die erste Kodezeile in CallbackStub setzt, wird der noch erreicht?

Johnny123 16. Jul 2019 10:45

AW: Event aus DLL für HotSpot Nutzen
 
if nEvent = STPAD_CALLBACK_HOTSPOT then

von der zeile aus sprint er direkt zum Ende hin

und als nEvent zeigt er eine zahl an 6194160

peterbelow 16. Jul 2019 13:34

AW: Event aus DLL für HotSpot Nutzen
 
Zitat:

Zitat von Johnny123 (Beitrag 1436837)
if nEvent = STPAD_CALLBACK_HOTSPOT then

von der zeile aus sprint er direkt zum Ende hin

und als nEvent zeigt er eine zahl an 6194160

Mh, ändere mal die calling convention für den callback typ und für CallbackStub auf stdcall statt cdecl.

Ich kenne mich nicht so besonders aus mit C/C++, vielleicht habe ich die Deklaration im Header falsch interpretiert.

Johnny123 16. Jul 2019 13:42

AW: Event aus DLL für HotSpot Nutzen
 
Delphi-Quellcode:
procedure CallbackStub(nEvent: integer; pData: Pointer; nDatasize: integer;
  PCustomPar: Pointer); stdcall;
Wenn ich da Stdcall oder cedc1 hinterstehen habe sagt er mir unterschiede in der aufrufkonvention

Johnny123 16. Jul 2019 15:21

AW: Event aus DLL für HotSpot Nutzen
 
ok problem mit der aufrufkonvention gelöst
bleibt der System Exception Fehler

hoika 16. Jul 2019 15:43

AW: Event aus DLL für HotSpot Nutzen
 
Halo,
hast Du das OCX-Beispiel mal ausprobiert?

Johnny123 16. Jul 2019 15:46

AW: Event aus DLL für HotSpot Nutzen
 
Hallo Heiko

meinst du das Active X ??

hoika 16. Jul 2019 16:10

AW: Event aus DLL für HotSpot Nutzen
 
Hallo,
ja.

Ansonsten würde ich bei der Firma mal nach einer Delphi-Unit fragen.
Wenn die das verkaufen wollen, sollten sie es anbieten ...

Johnny123 16. Jul 2019 16:12

AW: Event aus DLL für HotSpot Nutzen
 
Kommt leider für uns nicht in Frage die Active X version

hoika 16. Jul 2019 16:31

AW: Event aus DLL für HotSpot Nutzen
 
Hallo,
dann frag dort nach.

Johnny123 17. Jul 2019 11:33

AW: Event aus DLL für HotSpot Nutzen
 
Soweit funktioniert alles nur nach ausführen der Callback Funktion kommt immer noch die System Exception


Die Firma bietet nur eine Unit für Active X an bezüglich Delphi


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 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