AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zugriff auf lokale Variablen bei Callback aus DLL

Zugriff auf lokale Variablen bei Callback aus DLL

Ein Thema von kaju74 · begonnen am 10. Dez 2009 · letzter Beitrag vom 10. Dez 2009
Antwort Antwort
Seite 1 von 2  1 2   
kaju74

Registriert seit: 22. Okt 2003
185 Beiträge
 
#1

Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 14:46
Hallo.

Ich habe hier ein Verständnisproblem bzgl. DLL's und Callbacks. Also:

Ich habe ein Host-Programm, das PlugIns nachladen kann. Diese PlugIns sind ganz normale Delphi-DLL's,
die ein gemeinsames Interface implementieren. So weit so gut. Nachdem der Host ein PlugIn geladen hat, kann
ich über eine PlugIn-Methode ein Callback registrieren, der dann im PlugIn aufgerufen werden kann. Soweit
geht auch noch alles, soll heißen: PlugIn wird geladen, Callback wird registriert, eine PlugIn-Funktion
wird aufgerufen die wiederum die Callback-Routine im Host aufruft.

Nun mein Problem:

Nehmen wir an, wir haben eine Form (TfrmMain) mit folgendem Aufbau:

Delphi-Quellcode:
  TfrmMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    FLocalVar: string;
    procedure CallbackProc(ActionGUID: string; CallbackInfo: Pointer);
  public
    { Public-Deklarationen }
  end;
Die CallbackProc ist die Methode, die vom Plugin aufgerufen wird. So, hier nun die Implementation der
Methode:

Delphi-Quellcode:
procedure TfrmMain.CallbackProc(ActionGUID: string; CallbackInfo: Pointer);
begin
  ShowMessage('Aufgerufen vom PlugIn!');
end;
Das funktioniert....ABER...warum geht das hier nicht:

Delphi-Quellcode:
procedure TfrmMain.CallbackProc(ActionGUID: string; CallbackInfo: Pointer);
begin
  ShowMessage(FLocalVar);
end;
Es scheint so, das ich hier KEINEN Zugriff auf die lokalen Variablen habe. Setze ich "frmMain.FLocalVar" davor, geht
es, da ich die Klasse explizit angebe, aber warum geht's nicht auch ohne....

...und WIE LÖSE ICH DAS PROBLEM??? Die Variable "frmMain" gibts in meinem eigentlichen Programm nämlich gar nicht, da
sie dynamisch in einem Skeleton (über eine ClassFunction) generiert wird.

HILFE....

Lieben Gruß & Danke,
kaju

BDS2009 unter Windows7
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 14:50
Funktioniert es mit Self? Existiert eine Instanz (Objekt)?
Markus Kinzler
  Mit Zitat antworten Zitat
kaju74

Registriert seit: 22. Okt 2003
185 Beiträge
 
#3

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 14:53
Hallo.

Nein, auch mit SELF habe ich keinen Zugriff. Es kommt immer eine AV. Wenn ich wenigstens wüsste, warum das so ist. Ich habe echt das Gefühl, das ich innerhalb der im Host ausgeführten Callback-Funktion einen anderen Programmspeicher untergeschoben bekomme....


Aber danke

Gruß,
kaju
Miniaturansicht angehängter Grafiken
self_140.png  
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.170 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 14:53
Wie wird der Callback registriert? Wie ist der Funktionsprototyp der registrierungsfunktion? Wie wird der Callback aufgerufen?

Ach ja: Strings und DLL's. Hast du ShareMem oder FastMem eingebunden?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
kaju74

Registriert seit: 22. Okt 2003
185 Beiträge
 
#5

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 15:00
Hallo.

Der Zugriff auch Strings ist kein Problem...das wird alles übergeben, egal wie lang. Habe statt "SimpleShareMem" auch schon mit FastMM4 und diversen Optionen rumexperimentiert, ohne Erfolg.

Das PlugIn selber hält eine Liste der registrierten Callbacks. Hier mal der komplette Code:

Delphi-Quellcode:
unit MainFrm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, xpCore, xpPlugInMng;

type
{ TfrmMain }

  TfrmMain = class(TForm)
    btnTest: TButton;
    edtFirstName: TLabeledEdit;
    edtLastName: TLabeledEdit;
    mmoLog: TMemo;
    PlugInManager: TxpPlugInManager;
    procedure FormCreate(Sender: TObject);
    procedure PlugInManagerLoadPlugIn(Sender: TObject; PlugIn: TxpPlugIn);
    procedure PlugInManagerUnloadPlugIn(Sender: TObject; PlugIn: TxpPlugIn);
    procedure btnTestClick(Sender: TObject);
  private
    { Private-Deklarationen }
    FLocalVar: string;
    procedure CallbackProc(ActionGUID: string; CallbackInfo: Pointer);
  public
    { Public-Deklarationen }
  end;

var
  frmMain: TfrmMain;

implementation

uses
  SamplePlugInIntf;

{$R *.dfm}

{-------------------------------------------------------------------------------
  Procedure: TfrmMain.FormCreate
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: Sender: TObject
  Result:    None
-------------------------------------------------------------------------------}


procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FLocalVar := 'In der Wüste steht ein Reddisch - ferdisch 8-)';
end;

{-------------------------------------------------------------------------------
  Procedure: TfrmMain.PlugInManagerLoadPlugIn
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: Sender: TObject; PlugIn: TxpPlugIn
  Result:    None
-------------------------------------------------------------------------------}


procedure TfrmMain.PlugInManagerLoadPlugIn(Sender: TObject; PlugIn: TxpPlugIn);
begin
  mmoLog.Lines.Add(Format('PlugIn "%s" geladen...', [PlugIn.FileName]));
end;

{-------------------------------------------------------------------------------
  Procedure: TfrmMain.PlugInManagerUnloadPlugIn
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: Sender: TObject; PlugIn: TxpPlugIn
  Result:    None
-------------------------------------------------------------------------------}


procedure TfrmMain.PlugInManagerUnloadPlugIn(Sender: TObject; PlugIn: TxpPlugIn);
begin
  mmoLog.Lines.Add(Format('PlugIn "%s" entladen...', [PlugIn.FileName]));
end;

{-------------------------------------------------------------------------------
  Procedure: TfrmMain.CallbackProc
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: ActionGUID: string; CallbackInfo: Pointer
  Result:    None
-------------------------------------------------------------------------------}


procedure TfrmMain.CallbackProc(ActionGUID: string; CallbackInfo: Pointer);
var
  CallbackStruct: PCallbackStruct;
begin
  ShowMessage('B: ' + Self.FLocalVar);
  CallbackStruct := CallbackInfo;
  ShowMessage('Callback called:' + #13#13 + Trim(CallbackStruct^.FirstName + #32 + CallbackStruct^.LastName));
end;

{-------------------------------------------------------------------------------
  Procedure: TfrmMain.btnTestClick
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: Sender: TObject
  Result:    None
-------------------------------------------------------------------------------}


procedure TfrmMain.btnTestClick(Sender: TObject);
var
  SamplePlugIn: ISamplePlugIn;
begin
  ShowMessage('A: ' + FLocalVar);
  if not(PlugInManager.LoadPlugIn('SamplePlugIn', ISamplePlugIn, SamplePlugIn)) then
    raise Exception.Create(PlugInManager.LastError);
  try
    SamplePlugIn.RegisterCallbackProc(CallbackProc);
    SamplePlugIn.Execute(edtLastName.Text, edtFirstName.Text);
  finally
    PlugInManager.UnloadPlugIn(SamplePlugIn);
  end;
end;

end.
Und hier die relevanten PlugIn-Stellen:

Delphi-Quellcode:
unit SamplePlugInIntf;

interface

uses
  xpPlugInIntf;

type

{ TCallbackStruct }

  TCallbackStruct = record
    LastName: string;
    FirstName: string;
  end;
  PCallbackStruct = ^TCallbackStruct;

{ ISamplePlugIn }

  ISamplePlugIn = interface(IxpCustomPlugIn)
  ['{75C9A79A-DD40-4823-B7FC-17DB187B4526}']
    function RegisterCallbackProc(CallbackProc: TxpPlugInCallbackProc): Boolean;
    function FindCallbackProc: TxpPlugInCallbackProc;
    procedure Execute(const LastName, FirstName: string);
  end;

implementation

end.
UND:

Delphi-Quellcode:
unit SamplePlugInImpl;

interface

uses
  Classes, xpPlugInIntf, xpPlugInImpl, SamplePlugInIntf;

type
{ TCallbackProcStruct }

  TCallbackProcStruct = record
    CallbackProc: Pointer;
  end;
  PCallbackProcStruct = ^TCallbackProcStruct;


{ TSamplePlugIn }

  TSamplePlugIn = class(TxpCustomPlugIn, ISamplePlugIn)
  private
    { Private-Deklarationen }
    FCallbackProcs: TList;
  public
    { Public-Deklarationen }
    constructor Create;
    destructor Destroy; override;
    function RegisterCallbackProc(CallbackProc: TxpPlugInCallbackProc): Boolean;
    function FindCallbackProc: TxpPlugInCallbackProc;
    procedure Execute(const LastName, FirstName: string);
  end;

implementation

{ TSamplePlugIn }

{-------------------------------------------------------------------------------
  Procedure: TSamplePlugIn.Create
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: None
  Result:    None
-------------------------------------------------------------------------------}


constructor TSamplePlugIn.Create;
begin
  inherited Create;
  FCallbackProcs := TList.Create;
end;

{-------------------------------------------------------------------------------
  Procedure: TSamplePlugIn.Destroy
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: None
  Result:    None
-------------------------------------------------------------------------------}


destructor TSamplePlugIn.Destroy;
begin
  FCallbackProcs.Free;
  inherited;
end;

{-------------------------------------------------------------------------------
  Procedure: TSamplePlugIn.RegisterCallbackProc
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: CallbackProc: TxpPlugInCallbackProc
  Result:    Boolean
-------------------------------------------------------------------------------}


function TSamplePlugIn.RegisterCallbackProc(CallbackProc: TxpPlugInCallbackProc): Boolean;
var
  CallbackProcStruct: PCallbackProcStruct;
begin
  try
    New(CallbackProcStruct);
    CallbackProcStruct^.CallbackProc := @CallbackProc;
    FCallbackProcs.Add(CallbackProcStruct);
    Result := True;
  except
    Result := False;
  end;
end;

{-------------------------------------------------------------------------------
  Procedure: TSamplePlugIn.FindCallbackProc
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: None
  Result:    TxpPlugInCallbackProc
-------------------------------------------------------------------------------}


function TSamplePlugIn.FindCallbackProc: TxpPlugInCallbackProc;
var
  i: Integer;
  CallbackProcStruct: PCallbackProcStruct;
begin
  Result := nil;
  for i := 0 to FCallbackProcs.Count - 1 do
  begin
    CallbackProcStruct := PCallbackProcStruct(FCallbackProcs[i]);
    @Result := CallbackProcStruct^.CallbackProc;
    Break;
  end;
end;

{-------------------------------------------------------------------------------
  Procedure: TSamplePlugIn.Execute
  Author:    Marc Hoffmann
  DateTime:  2009/12/10
  Arguments: const LastName, FirstName: string
  Result:    None
-------------------------------------------------------------------------------}


procedure TSamplePlugIn.Execute(const LastName, FirstName: string);
var
  CallbackProc: TxpPlugInCallbackProc;
  CallbackStruct: TCallbackStruct;
begin
  CallbackProc := ISamplePlugIn(Self).FindCallbackProc;
  if not(Assigned(CallbackProc)) then
    Exit;
  CallbackStruct.LastName := LastName;
  CallbackStruct.FirstName := FirstName;
  CallbackProc('12345', @CallbackStruct);
end;

end.
Bringt Euch das weiter?

Lieben Gruß,
kaju
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.170 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 15:03
Wie ist TxpPlugInCallbackProc definiert?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
kaju74

Registriert seit: 22. Okt 2003
185 Beiträge
 
#7

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 15:06
Uppps....vergessen:

  TxpPlugInCallbackProc = procedure(ActionGUID: string; CallbackInfo: Pointer) of object; Gruß,
kaju
  Mit Zitat antworten Zitat
kaju74

Registriert seit: 22. Okt 2003
185 Beiträge
 
#8

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 15:17
Okay...da ich echt am verzweifeln bin, anbei mal das komplette Paket...wenn's läuft's, dürfen's alle benutzen )

Lieben Gruß,
kaju
Angehängte Dateien
Dateityp: zip plugindemo_172.zip (18,0 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.606 Beiträge
 
#9

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 15:48
Das problem ist ein anderes. Der Callback erwartet eine FUNKTION, keine Methode eines Objektes.
Oder anders gesagt, der 'Self' pointer, der auf das Objekt verweits, und der als erstes (unsichtbares) Argument bei Delphi erwartet wird, ist NIL.

Ich suche gerade mal eine Lösung dafür und melde mich dann wieder

Edit: Hier haben wir den besagten Thread: http://www.delphipraxis.net/internal...?p=74609#74609
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
kaju74

Registriert seit: 22. Okt 2003
185 Beiträge
 
#10

Re: Zugriff auf lokale Variablen bei Callback aus DLL

  Alt 10. Dez 2009, 15:56
Hallo.

Ich zitiere mal einen Satz auf "Findet Nemo":

Zitat:
Ich finde Dich echt nett, aber ich habe keine Ahnung, was Du mir sagen willst
)))

Ich versteh's hoffentlich, wenn das Problem gelöst ist )

Vielen Dank für Deine Mühe,
kaju
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:13 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