AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) DLL und Callback-Funktion: Hostprogramm reagiert nicht?
Thema durchsuchen
Ansicht
Themen-Optionen

DLL und Callback-Funktion: Hostprogramm reagiert nicht?

Ein Thema von romber · begonnen am 28. Mai 2013 · letzter Beitrag vom 30. Mai 2013
Antwort Antwort
Seite 2 von 2     12   
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.166 Beiträge
 
Delphi 10 Seattle Professional
 
#11

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 16:26
Nochmal von vorne...
  1. Client "Hauptprogramm" bindet DLL ein
  2. Hauptprogramm erzählt der DLL, welche Funktion es später einmal aufrufen soll, wenn es Datenmengen abzugeben hat
  3. Die DLL tut viele Dinge, darunter auch mehrere Threads öffnen
  4. Mehrere der Threads aus der DLL entscheiden sich nun innerhalb einer kurzen Zeitspanne, die Datenablieferungsfunktion aufzurufen
  5. Die Funktion soll erst einmal nichts anderes tun, als die Daten, die sie übergeben bekommt, als Text in eine Memo zu werfen

Alles richtig bis hier?
Genau so ist es. Wohlgemerkt dass es sich bei dem Hostprogramm nur um eine kleine Testanwendung handelt.

Wenn ich zumindest das Problem verstehe, dann ist es die Tatsache, dass (der Thread aus) der DLL mit der ganzen VCL-Geschichte des Hauptprogramms nichts am Hut hat. Und somit beispielsweise auch erst garnichts im Kontext des Hauptthreads ausführen kann. Richtig?
Aber die DLL greifft doch auf die Callback-Funktion zu, die wiederum auf die TMemo zugreifft. Oder habe ich die Frage falsch verstanden?

Ich würde die Datenablieferungsfunktion so bauen, dass hier Daten einfach nur abgelegt werden. Beispielsweise in einer verketteten Liste (natürlich entsprechend geschützt, z.B. mit einem kritischen Abschnitt). In deinem Hauptprogramm würde ich z.B. jede halbe Sekunde hingehen und schauen, ob mittlerweile neue Daten vorliegen. Wenn ja, kann man die ja anzeigen.
In dem eingentlichen Client wird das auch so sein. Die Daten werden von der Callback-Funktion aufbereitet und einem s.g. Custom Date Source hinzugefügt, das wiederrum einen TObejctList als Datencontainer benutzt. Kommen neue Daten an, ruft Custom Data Source eine Funktion auf, die die neue Daten im Grid anzeigt.

Trotzdem würde ich gerne wissen, warum sich das Testprogramm aufhängt.

Geändert von romber (29. Mai 2013 um 16:31 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#12

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 17:15
Nur schnell zusammengestöpselt, ein Rumpf , Fehlerkorrektur erbeten ...


DLL

Delphi-Quellcode:
library Project2;

uses
  SysUtils,
  Classes;

Type

   TCallBackProc=Procedure(info:PChar);
   TDummyThread=Class(TThread)
     Procedure Execute;override;
   End;

{$R *.res}
Var
  SaveExit:Pointer;
  TheCallBackProc:TCallBackProc;

procedure LibExit;far;
begin
     ExitProc := SaveExit;
end;


Procedure InitDLL(CallBackProc:TCallBackProc);
var
 i:Integer;
begin
   TheCallBackProc := CallBackProc;
   for I := 0 to 100 do
     with TDummyThread.Create(false) do FreeOnTerminate := true;
end;

exports
InitDLL index 1;

{ TDummyThread }

procedure TDummyThread.Execute;
begin
  inherited;
  Sleep(Random(2000));
  if Assigned(TheCallBackProc) then TheCallBackProc(PChar(Format('Irnedein Testtext %d',[ThreadID])));
end;

begin
     SaveExit := ExitProc;
     ExitProc := @LibExit;
end.

Testprogramm


Delphi-Quellcode:
unit Unit3;

interface

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

type
   TCallBackProc=Procedure(info:PChar);
   TInitDLL=Procedure (p:TCallBackProc);

  TForm3 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    FH:Thandle;
    FInitDLL:TInitDLL;

  public
    { Public-Deklarationen }
  end;

var
  Form3: TForm3;

implementation
{$R *.dfm}
procedure SyncAddToMemo(const s:String);
begin
  Form3.Memo1.Lines.add(s);
  Application.ProcessMessages;
end;


procedure CallBack(P:PChar);
begin
    TThread.Synchronize(nil,Procedure begin SyncAddToMemo(P) end)
end;



procedure TForm3.Button1Click(Sender: TObject);
begin
  if Assigned(FInitDLL) then FInitDLL(@CallBack);
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
   FH := LoadLibrary(Pchar(ExtractFilePath(Paramstr(0))+'Project2.dll'));
   if FH<>0 then
       FInitDLL := GetProcAddress(FH,'InitDLL');

end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
  if FH<>0 then FreeLibrary(FH);

end;

end.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#13

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 17:20
@bummi

Mach aus dem TThread.Synchronize ein TThread.Queue und das Application.ProcessMessages kannst du unter den Tisch fallen lassen

Obwohl ich sowieso nicht sehe, wozu das wirklich gut sein soll ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 17:21
Hast du denn mal die Trial von Eurekalog oder MadExcept ausprobiert (installiert und für beide Projekte, also Hauptprogramm und DLL, aktiviert)? Du musst die ja nicht sofort kaufen, sondern kannst es erst einmal ausprobieren. Du wirst aber denke ich merken, dass die durchaus sehr hilfreich sind und ihr Geld wert sind.

Denn das Programm hängt sich deinem Screenshot zufolge ja nicht auf, sondern hat einfach eine unbehandelte Exception. Die findest du auch in den Dr. Watson Debuglogs, sofern die auf deinem PC aktiviert gelassen sind. Den Stacktrace bekommst du da aber nur in aufbereiteter Form, wenn du .dbg Dateien aus den Delphi-Debugdateien erzeugst.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#15

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 17:39
@SirRufo für Queue müsste ich den Thread als Object aus der DLL zurückgeben.
Der Hintergrund was eigentlich nur zu zeigen wo IMHO synchronisiert werden muss.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#16

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 18:08
@SirRufo für Queue müsste ich den Thread als Object aus der DLL zurückgeben.
Der Hintergrund was eigentlich nur zu zeigen wo IMHO synchronisiert werden muss.
Nö, geht genauso wie mit dem Sychronize (liegen beide als class procedure vor)

http://docwiki.embarcadero.com/Libra....TThread.Queue
http://docwiki.embarcadero.com/Libra...ad.Synchronize
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#17

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 18:46
@SirRufo ich lasse mich gerne belehren ich hatte den Fehler bei der Übergabe von nil auf den fehlenden Thread bezogen.
Du hast recht dieser muss nicht übergeben werden, trotzdem fliegt mir das ganze bei ausreichender Threadanzahl mit Queue um die Ohren, ich vermute weil der übergebene PChar bis zum abarbeiten der Queue ungültig geworden ist.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 19:12
Deshalb nimmt man da ja auch keinen PChar, sondern z.B. einen WideString, wenn etwas asynchron weiterverarbeitet wird.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#19

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 29. Mai 2013, 20:09
Wenn der PChar in einer lokalen string Variable gespeichert wird dann sollte dieser auch problemlos per Queue weitergegeben werden können.

Widestring ist da natürlich wesentlich nkomplizierter
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: DLL und Callback-Funktion: Hostprogramm reagiert nicht?

  Alt 30. Mai 2013, 11:10
Wenn der PChar in einer lokalen string Variable gespeichert wird dann sollte dieser auch problemlos per Queue weitergegeben werden können.
Da bin ich mir nicht so sicher. Wenn du einen PChar nach dem TThread.Queue noch veränderst, wird ja in der Prozedur in der Schlange auch der veränderte Wert benutzt. Einfaches Beispiel:
Delphi-Quellcode:
procedure TTest.Execute;
var
  a: PChar;
begin
  a := PChar(DupeString('f', 30)); // um keine Konstante zu haben
  TThread.Queue(nil, procedure
    begin
      ShowMessage(a); // fdsdfsd
    end);
  a := 'fdsdfsd';
end;
Wo da wirklich der Speicher freigegeben wird, wäre ich mir jetzt nicht so sicher...
(und ich habe grad keine Lust zu schauen )
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 15:09 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