AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit TComPort in dll

Ein Thema von iphi · begonnen am 28. Feb 2022 · letzter Beitrag vom 1. Mär 2022
Antwort Antwort
iphi

Registriert seit: 13. Feb 2009
262 Beiträge
 
Delphi 7 Personal
 
#1

Problem mit TComPort in dll

  Alt 28. Feb 2022, 09:50
Hallo,

ich versuche gerade verzweifelt die TComPort-Komponente mit ihrem Event Handler in einer dll zum Laufen zu bringen. Und ja, ich habe in der dll eine eigene Message-Loop am Laufen. Zum Test habe ich in der dll zusätzlich einen Timer erzeugt, der auch munter vor sich hin tickt. Nur der Com-Port löst keinen Event bei einlaufenden Daten aus. ???

Hier mein Code:
Der eigentliche dll-code:
Delphi-Quellcode:
library TestDLL;

uses
  SysUtils,
  Classes,
  Windows,
  UCom in 'UCom.pas';

function _Init: boolean; export; cdecl;
begin
{$IFDEF DEBUG_CON}
FreeConsole;
AllocConsole;
writeln('UserDLL function "Init" called');
{$ENDIF}
DecimalSeparator:='.';
Result:=DoInit;
end;

procedure _Close; export; cdecl;
begin
DoClose;
{$IFDEF DEBUG_CON}
writeln('UserDLL function "Close" called');
writeln('Hit return to continue...');
//readln;
FreeConsole;
{$ENDIF}
end;

function _Do:boolean; export; cdecl;
begin
{$IFDEF DEBUG_CON}
writeln('UserDLL function "Do" called.');
{$ENDIF}
result:=DoIt;
end;

exports _Init;
exports _Close;
exports _Do;

begin
end.
Die UCom-Unit:
Delphi-Quellcode:
unit UCom;

interface

uses Classes, Messages, Windows, SysUtils, CPort, ExtCtrls;

type
  THandler=Class
  procedure ComData(Sender: TObject; Count: Integer);
  procedure TimerTick(sender: TObject);
  end;

type
  TMessageLoopThread = class(TThread)
  private
    procedure WndProc(var Msg:TMessage);
  protected
    procedure Execute; override;
  public
    MsgLoopHandle: HWND;
    constructor Create(ThreadPriority: TThreadPriority);
  end;

function DoInit: boolean;
function DoIt: boolean;
Procedure DoClose;

implementation

var
  CP: TComPort;
  handler: THandler;
  MsgLoop: TMessageLoopThread;
  MsgLoopActive: boolean;

  Timer: TTimer;

const DEBUG=true;

constructor TMessageLoopThread.Create(ThreadPriority: TThreadPriority);
begin
  inherited Create(true);
  Priority := ThreadPriority;
  FreeOnTerminate := true;
  MsgLoopActive:=true;
  Suspended:=false;
end;

procedure TMessageLoopThread.Execute;
var msg:Tmsg;
begin
if DEBUG then Writeln('message loop started');
MsgLoopHandle:=allocatehwnd(WndProc); //Windowhandle für Messages
try
 //[weitere Initialisierungen]
 while getMessage(msg,0,0,0) do //warten auf Message solange nicht WM_QUIT
   begin
     DispatchMessage(msg); //verteilen auf das entsprechende Fenster (gibt hier allerdings eh nur eins)
   end;
finally
 Deallocatehwnd(MsgLoopHandle);
end;
if DEBUG then Writeln('message loop stopped');
MsgLoopActive:=false;
end;

procedure TMessageLoopThread.WndProc(var Msg:TMessage);
begin
  dispatch(msg);
end;

procedure THandler.ComData(Sender: TObject; Count: Integer);
var
    s: string;
begin
CP.ReadStr(s,count);
write('>>COMHANDLER>> ',s);
end;

var nt: integer=0;
procedure THandler.TimerTick(sender: TObject);
begin
 writeln('Timer: ',nt);
 inc(nt);
end;

function DoInit: boolean;
begin
Handler:=THandler.Create;
MsgLoop:=TMessageLoopThread.Create(TPNormal);
Timer:=TTimer.Create(nil);
Timer.OnTimer:=Handler.TimerTick;
Timer.Interval:=2000;
Timer.Enabled:=true;
CP:=TComPort.Create(nil);
CP.Port:='COM4';
CP.FlowControl.FlowControl:=fcHardware;
CP.FlowControl.ControlDTR:=dtrEnable;
CP.BaudRate:=br115200;
CP.DataBits:=dbEight;
CP.StopBits:=sbOneStopBit;
CP.Parity.Bits:=prNone;
CP.TriggersOnRxChar:=true;
CP.OnRxChar:=Handler.ComData;
Try CP.Open; except end;
if CP.Connected then
  writeln ('DLL connected')
  else
  writeln('DLL NOT connected');
end;

function DoIt: boolean;
begin
if CP.Connected then
  CP.WriteStr('++ver'#13#10);
end;

Procedure DoClose;
begin
Timer.Enabled:=false;
FreeAndNil(Timer);
PostMessage(MsgLoop.MsgLoopHandle,WM_QUIT,0,0);
CP.Close;
FreeAndNil(CP);
while MsgLoopActive do sleep(10);
FreeAndNil(Handler);
end;

end.
Wie gesagt, der Timer ist nur dazu da, die Funktion der MessageLoop zu checken.
Die Funktion DoIt sendet einen String zum Com-Port raus, auf den sofort ein anderer String als Antwort zurück kommt. Ich sehe am angeschlossenen Gerät, dass die Antwort tatsächlich gesendet wird. Der Handler ComData wird aber nicht aufgerufen.

Ich habe exakt denselben ComPort-Code mal direkt in eine GUI gepackt, CP ebenfalls dynamisch erzeugt wie in der dll. Da funktioniert es wie erwartet.

Hat jemand eine Idee, was da schief geht?
Wahrscheinlich sehe ich den Wald vor lauter Bäumen nicht. Danke für Eure Hilfe!
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
701 Beiträge
 
Delphi 12 Athens
 
#2

AW: Problem mit TComPort in dll

  Alt 28. Feb 2022, 15:15
versuch mal, die TComPort-Komponente innerhalb des threads zu erzeugen.
Peter Below
  Mit Zitat antworten Zitat
iphi

Registriert seit: 13. Feb 2009
262 Beiträge
 
Delphi 7 Personal
 
#3

AW: Problem mit TComPort in dll

  Alt 28. Feb 2022, 16:15
Danke für die Idee, ändert aber leider nichts.
Der ComPort-Handler wird leider nach wie vor nicht ausgelöst.

Die TComPort-Komponente wurde schon länger nicht mehr weiterentwickelt. Gibt es da vielleicht was neueres, mit dem ich mehr Glück haben könnte?
  Mit Zitat antworten Zitat
TurboMagic

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

AW: Problem mit TComPort in dll

  Alt 28. Feb 2022, 20:54
Schon Mal TComPortDrv V3.0 aus GetIt probiert?
  Mit Zitat antworten Zitat
EmWieMichael

Registriert seit: 28. Mär 2012
103 Beiträge
 
#5

AW: Problem mit TComPort in dll

  Alt 1. Mär 2022, 07:30
Die Ergebnisse von DoIt und DoInit sind undefiniert.

Geändert von EmWieMichael ( 1. Mär 2022 um 07:32 Uhr)
  Mit Zitat antworten Zitat
iphi

Registriert seit: 13. Feb 2009
262 Beiträge
 
Delphi 7 Personal
 
#6

AW: Problem mit TComPort in dll

  Alt 1. Mär 2022, 15:54
Zitat:
Schon Mal TComPortDrv V3.0 aus GetIt probiert?
Geht das in Delphi7?

Zitat:
Die Ergebnisse von DoIt und DoInit sind undefiniert.
Weiß ich, soweit bin ich nicht gekommen. Ist für das beschriebene Problem aber belanglos.
  Mit Zitat antworten Zitat
iphi

Registriert seit: 13. Feb 2009
262 Beiträge
 
Delphi 7 Personal
 
#7

AW: Problem mit TComPort in dll

  Alt 1. Mär 2022, 16:54
Habs gefunden.

CP.SyncMethod:=smNone;
...muss gesetzt sein, dann gehts.

Geändert von iphi ( 1. Mär 2022 um 16:56 Uhr)
  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 11:38 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