Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DLL Parameterübergabe (https://www.delphipraxis.net/94497-dll-parameteruebergabe.html)

bluescreen25 22. Jun 2007 08:18


DLL Parameterübergabe
 
Hallo, ich habe eine DLL mit einer Form, welche von der Hauptapplikation aufgerufen wird.

Nach dem beschriebenen Plugin-Verfahren : function FormShowNormal(parent: Pointer): Pointer; stdcall;

Mein Problem ist, das ich aus der DLL dem Hauptprogramm mitteilen möchte, wenn die DLL-Form geschlossen wird.Ich möchte mir das ständige Abfragen aus dem Hauptprogramm heraus ersparen.

Gruß, bluescreen25

SirThornberry 22. Jun 2007 08:24

Re: DLL Parameterübergabe
 
dann musst du der DLL eine Callbackfunktion mitgeben.
Beispiel:

DLL:
Delphi-Quellcode:
var
  gCallBack: procedure(); stdcall;

procedure SetCallBack(ACallback: Pointer);
begin
  @gCallBack := ACallBack;
end;

//OnFormClosed
if Assigned(gCallBack) then
  gCallBack();
Hauptprogramm
Delphi-Quellcode:
procedure GCallbackProcedure();
begin
  ShowMessage('Form wurde geschlossen');
end;

[...]
DLLProcedure_SetCallBack(@GCallBackProcedure);

bluescreen25 22. Jun 2007 10:25

Re: DLL Parameterübergabe
 
Zitat:

Zitat von SirThornberry
dann musst du der DLL eine Callbackfunktion mitgeben.

[...]
DLLProcedure_SetCallBack(@GCallBackProcedure);
[/delphi]

Sorry, aber da reicht mein Verständnis noch nicht.
Ich habe versucht das Beispiel mal einzusetzen, aber gerade die letzte Zeile von dir verstehe ich noch nicht.

Gruß, bluescreen25

SirThornberry 22. Jun 2007 10:38

Re: DLL Parameterübergabe
 
ok. Die Theorie:
Callback steht für Rückruf bzw. Rückfrage
und genau darum geht es auch.

Damit die DLL in deinem Hauptprogramm eine Funktion aufrufen kann wenn etwas passiert (zum Beispiel das Form geschlossen wird), muss die DLL natürlich wissen welche Funktion sie aufrufen muss.

Dafür teilst du der DLL die Speicher-Adresse deiner Funktion mit.
Die Adresse einer Funktion oder Variablen bekommst du durch vorranstellen des @
Mit
Delphi-Quellcode:
@MeineFunktion
bekommst du also die Speicheradresse von MeineFunktion heraus.

Diese musst du der DLL übergeben. Die DLL merkt sich die Adresse und ruft dann bei Eintreten des Ereignisses eben die Funktion an dieser Adresse auf.

deine dll:
Delphi-Quellcode:
var
  gCallBack: procedure() = nil; //Variable für die Adresse der Funktion aus dem Hauptprogramm

//Diese Funktion muss das Hauptprogramm aufrufen um der DLL die Adresse mitzuteilen
procedure SetCallBack(ACallback: Pointer);
begin
  @gCallBack := ACallBack;
end;

[...]
//OnFormClosed
// Wenn eine Callbackfunktion mitgeteilt wurde (diese also ungleich nil ist)
if Assigned(gCallBack) then
  gCallBack(); //Callbackfunktion aufrufen.
[...]

exports
  SetCallBack; //Damit das Hauptprogramm uns die Adresse mitteilen kann müssen wie die dafür benötigte Funktion exportieren
Hauptprogramm
Delphi-Quellcode:
procedure SetCallBack(ACallBack: Pointer); external 'deinedll.dll';
[...]
//Diese Funktion soll die DLl aufrufen wenn sie fertig ist (dafür übergeben wir an anderer Stelle die Adresse)
procedure GCallbackProcedure();
begin
  ShowMessage('Form wurde geschlossen');
end;

//durch aufruf dieser Funktion teilen wir der dll die Adresse der Callback-Funktion mit
procedure DerDllDieAdresseMitteilen();
begin
  //Die Funktion in der DLL aufrufen mit welcher wir der DLL mitteilen an welcher Adresse die Callback-Funktion liegt
  SetCallBack(@GCallbackProcedure);
end;

bluescreen25 22. Jun 2007 10:52

Re: DLL Parameterübergabe
 
Zitat:

Zitat von SirThornberry
ok. Die Theorie:
Callback steht für Rückruf bzw. Rückfrage
und genau darum geht es auch.

...

Wow, vielen Dank, das war super verständlich und nachvollziehbar.

Ich lege das unter meine Tuts ab.

Gruß, bluescreen25


Oha soweit die Theorie...alles verstanden, umgesetzt..geht nicht..dann copy & paste und leider immer noch nix....

Ich bekomme einfach die procedure nicht angepeilt..

Gruß bluescreen25

Muetze1 22. Jun 2007 13:34

Re: DLL Parameterübergabe
 
Zitat:

Zitat von bluescreen25
Ich bekomme einfach die procedure nicht angepeilt..

Den Fachbegriff "angepeilt" kenne ich noch nicht. Könntest du den näher erklären bzw. beschreiben wo es denn zZ noch hakt? Dann kann ich dir auch vllt. helfen.

bluescreen25 22. Jun 2007 13:57

Re: DLL Parameterübergabe
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von bluescreen25
Ich bekomme einfach die procedure nicht angepeilt..

Den Fachbegriff "angepeilt" kenne ich noch nicht. Könntest du den näher erklären bzw. beschreiben wo es denn zZ noch hakt? Dann kann ich dir auch vllt. helfen.

Ok sorry für das Unfachmännische....

MainProg:

Delphi-Quellcode:
procedure GCallbackProcedure();
procedure DerDllDieAdresseMitteilen();
Delphi-Quellcode:
...
...
implementation



{$R *.dfm}

const
  dllname = 'vosk.dll';


procedure FormShowNormal(parent: Pointer); stdcall; external dllname;
procedure SetCallBack(ACallBack: Pointer); stdcall; external dllname;


procedure GCallbackProcedure();
begin
  ShowMessage('Form wurde geschlossen');
end;


procedure DerDllDieAdresseMitteilen();
begin
  SetCallBack(@GCallbackProcedure);
end;
...
...
Plus ein Aufruf von DerDllDieAdresseMitteilen.


Dll:

Delphi-Quellcode:
library vosk;

uses
  Windows,
  virtualosk in 'virtualosk.pas' {frmOSK};

var
  DLLProcNext: procedure(Reason: Integer); stdcall;
 

exports
  FormShowModal,FormShowNormal,SetCallBack;

...

Delphi-Quellcode:
unit virtualosk;
...
...
var gCallBack: procedure()=nil;
...
...
procedure FormShowModal(parent: Pointer); stdcall;
function FormShowNormal(parent: Pointer): Pointer; stdcall;
procedure SetCallBack(ACallback: Pointer);stdcall;

implementation

{$R *.dfm}


procedure SetCallBack(ACallback: Pointer);
begin
  @gCallBack := ACallBack;
end;
...
...
procedure TfrmOSK.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Assigned(gCallBack) then gCallBack();
  // Form beim Schließen freigeben
  Action := caFree;
  windows.SetActiveWindow(hForeground); //vor beenden den Focus zurück auf cAVe
end;

Hmm, so wie es jetzt ist, starte ich mein Hauptprogramm, rufe dort die Form aus der Dll auf, dann hängt es sich auf.


Gruß,bluescreen25

Muetze1 22. Jun 2007 14:06

Re: DLL Parameterübergabe
 
Also vom Code her sehe ich erstmal nichts in Sachen Callback. Der Callback sollte wenn, eh erst ausgelöst werden, wenn du das Formular schliesst. Von daher liegt es nicht unbedingt am Callback sondern wohl eher an der Form und anzeigen dieser. Funktioniert der genannte Teil denn für sich alleine problemlos?

bluescreen25 22. Jun 2007 14:13

Re: DLL Parameterübergabe
 
Zitat:

Zitat von Muetze1
Also vom Code her sehe ich erstmal nichts in Sachen Callback. Der Callback sollte wenn, eh erst ausgelöst werden, wenn du das Formular schliesst. Von daher liegt es nicht unbedingt am Callback sondern wohl eher an der Form und anzeigen dieser. Funktioniert der genannte Teil denn für sich alleine problemlos?

Ja es funktionierte die Form aus der DLL problemlos...es ist eine überlagerte virtuelle Tastatur, die den Focus immer zurück auf die letze Form bringt. Alles OK soweit.

Ich brauche allerdings eine Form_closed Meldung zurück an die Mainapplikation, damit ich später den Focus einmal zurück auf die Form der Mainapp bringen kann.

Damit ich nicht immer den Status der Dll abfragen muss, wollte ich, das die Dll der Main sagt, wenn die Form geschlossen ist.

Delphi-Quellcode:
procedure GCallbackProcedure();
begin
  ShowMessage('Form wurde geschlossen');
end;


procedure DerDllDieAdresseMitteilen();
begin
  SetCallBack(@GCallbackProcedure);
end;
Wenn ich hier hinter den procedure ein stdcall setze, dann hängt es nimmer, aber eine Meldung erhalte ich trotzdem nicht von der DLL

Gruß,bluescreen25


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