我正在尝试在delphi中编写一个简单的CPort应用程序。
我希望它听一个端口,收到一条消息后,它将等待4秒然后发送一个字符串作为回应。
unit Tests.Mocks.Refractometer;
interface
uses
CPort,
Classes
;
type
TRefractometerMock = class
strict private
MockRunThread : TThread;
ComPort : TComPort;
ComDataPacket: TComDataPacket;
public
procedure Open;
procedure HandlePacket(Sender : TObject; const Str : String);
constructor Create; overload;
constructor Create(BaudRate : TBaudRate; Port : String); overload;
destructor Destroy; override;
end;
implementation
uses
SysUtils,
StrUtils
;
procedure TRefractometerMock.HandlePacket(Sender : TObject; const Str : String);
begin
MockRunThread.Start;
end;
procedure TRefractometerMock.Open;
begin
ComPort.Open;
end;
constructor TRefractometerMock.Create(BaudRate : TBaudRate; Port : String);
begin
Self.Create;
Self.ComPort.Port := Port;
Self.ComPort.BaudRate := BaudRate;
end;
constructor TRefractometerMock.Create;
begin
inherited;
ComPort := TComPort.Create(nil);
ComDataPacket := TComDataPacket.Create(nil);
ComDataPacket.ComPort := ComPort;
ComDataPacket.OnPacket := HandlePacket;
MockRunThread := TThread.CreateAnonymousThread
(
procedure
begin
Sleep(4000);
Self.ComPort.WriteStr('nD=1.33308;');
end
);
end;
destructor TRefractometerMock.Destroy;
begin
if Assigned(Self.ComPort) then FreeAndNil(Self.ComPort);
if Assigned(ComDataPacket) then FreeAndNil(ComDataPacket);
if Assigned(MockRunThread) then FreeAndNil(MockRunThread);
inherited;
end;
end.
使用此单元我可以使用以下代码
开始聆听
RefractometerMock := TRefractometerMock.Create(TBaudRate.br9600, 'COM7');
try
RefractometerMock.Open;
Sleep(8000);
finally
FreeAndNil(RefractometerMock);
end;
另请注意,我正在使用com0com在端口COM6
和COM7
之间创建桥接。
我在端口COM6
问题在于即使我发送了一条带putty的消息,在释放HandlePacket
对象之前也不会调用TRefractometerMock
方法。
首先
然后
然后
最后
我甚至不确定这是怎么可能的,因为我认为这个物体已经被毁坏了。
答案 0 :(得分:3)
您正在Sleep(8000)
阻止主线程。这意味着com端口驱动程序无法调用HandlePacket
方法。
当睡眠结束时,处理任何事都为时已晚,因为一切都已被释放。
由于您正在处理匿名线程的生命周期,因此应将FreeOnTerminate
属性设置为false。并在匿名线程之后释放com端口。
使用计时器代替Sleep()
来电。
答案 1 :(得分:0)
我没有看到ComDataPacket的任何设置。来自帮助:Packet ends when one of stop conditions occurs
。你有没有定义这些停止条件?
您是否在简单的独立应用程序中使用ComDataPacket检查了数据接收,没有中间类?
答案 2 :(得分:0)
由于布莱恩弗罗斯特想要这里的代码,这太大了,不适合评论。
创建一个简单的表单
type
TFrmMockRefrac = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
RefractometerMock : TRefractometerMock;
{ Public declarations }
end;
var
FrmMockRefrac: TFrmMockRefrac;
在没有Sleep
功能的情况下处理创建和销毁
procedure TFrmMockRefrac.FormCreate(Sender: TObject);
begin
RefractometerMock := TRefractometerMock.Create(TBaudRate.br9600, 'COM7');
RefractometerMock.Open;
end;
procedure TFrmMockRefrac.FormDestroy(Sender: TObject);
begin
FreeAndNil(RefractometerMock);
end;