在Delphi中使用串行端口组件从线程导入(v4)中的事件?

在Delphi中使用串行端口组件从线程导入(v4)中的事件?,delphi,tcomport,Delphi,Tcomport,几年前,在我的一个应用程序中,当某个应用程序必须对某些串行事件做出非常快速的响应时,我将串行处理移到了一个线程上 这是在BDS2006中,有一个较旧的版本(大约3.x?),它是通过在tthread.execute中使用如下代码来完成的: while ... begin events:=[evRxChar]; { Prepare a stop event for killing a waiting communication wa

几年前,在我的一个应用程序中,当某个应用程序必须对某些串行事件做出非常快速的响应时,我将串行处理移到了一个线程上

这是在BDS2006中,有一个较旧的版本(大约3.x?),它是通过在tthread.execute中使用如下代码来完成的:

    while ...
          begin
          events:=[evRxChar];
          { Prepare a stop event for killing a waiting communication wait. }
           try
             comport1.WaitForEvent(events,stopevent.handle,500);
             if evRxChar in events then
               ComPort1RxChar(comport1,comport1.InputCount); // method of thread.
           on e: exception do {only logs} ;
           end;
初始化就像

procedure TSerThread.initcomport(comportname:string='COM1');
begin
 comport1:=tcomport.create(nil);
 ComPort1.BaudRate:=br115200;
 ComPort1.DataBits:=dbEight;
 ComPort1.Port:=comportname;

 ComPort1.StopBits:=sbOneStopBit;
 ComPort1.Events:=[];
 ComPort1.Connected:=true;

 StopEvent := TEvent.Create(nil,{ManualReset}false,{InitialState}false,'StopEvent');
end;
rxchar方法使用 comport1.readstr()

我最近不得不把它挖出来,发现它在我的Delphi XE中不起作用,它有tcomport4。从消息来源看,我看到一些评论 comport4改变了它处理内部线程的方式(“overlapped”属性),但是默认值似乎是“true”,它的注释是“classic”,而我

假设这意味着与旧版本兼容

请注意,这些协议是二进制的,所有字符串、字符、ansistring和ansichar的更改都像我在正常的主线程版本中所做的一样

现在真正的问题是:

  • 有人让tcomport4在线程中工作吗
  • 上面有没有明显的错误
  • 还是需要迁移到其他组件
  • 我仍在调试正在发生的事情,但我很匆忙,而我发布这篇文章的目的是希望能够快速获得指针

    更新

    我重新安装了一个旧的turbodelphi副本,并用v3验证了它的有效性。我修复了代码路径中的一个小错误,它与我的想法有点不同(不是在上面的代码中)

    这使我能够更好地描述dxe/comportv4和bds2006/comportv3之间的行为;v4代码生成更多的读取事件(数百次/秒)。看起来读操作并没有从传入队列中删除读字符

    更新2

    我用最新版本做了一个快速测试,并做了必要的重新排列(kill string函数用于基本上是二进制协议)。我被卡住了一段时间,因为应用程序在启动时崩溃了,但那是因为我使用gnugettext,而Comport打包了一个不同的(甚至是非unicode?)版本。但是在那之后它就开始工作了

    不幸的是,将更改传播回生产版本(完全编写协议解码)有点冒险,因此我必须使用中间版本(4.0和4.11f之间)进行测试。我会在适当的时候这样做,有没有任何建议哪一个版本是最后一个readstr(ansisting)版本

    更新3

    最后,我简单地重命名了4.11f单元,并将其与旧版本并行使用,将4.11f用于线程化代码库,旧的用于维护现有代码


    从长远来看,我可能只是简单地使用waitforevent代码,并创建自己的版本。它的主要问题是不可能看到等待是否在超时、stopevent或其他情况下终止。这意味着您需要另一个计时器,例如定期发送。您需要升级到最新的stable 4.11版本。

    导入的确切版本是什么?(在不同的4.x版本中有很多不同之处和很多奇怪的bug。)4.0中有一个字符串“W.Postma于2008年10月为Delphi2009修复”。2009年夏天,我在一个名为“tcomport4beta”的档案中得到了这个版本,它有一些严重的bug。您使用的事件处理代码在Delphi2009中几乎不起作用,而在XE版本中则完全不起作用。我会升级到稳定的发布版本。请注意,4.0和4.11的字符串类型有所不同。从您发布的代码来看,您似乎没有选择我的默认路径,即使用Anistring for作为序列代码,因此我建议您使用最新的4.11版本。您对Delphi 2009年之前和2009年之后的Unicode问题了解多少?:-)正如您所知,在Delphi 2006/2007时代,一个字符很容易就等于从com端口输入的一个字节。到目前为止,delphi中的字符是一个Unicode实体,虽然TComPort不足以读取两个字节并将其称为“Unicode字符”,但如果没有正确地移植到Unicode delphi,您仍然可能会遇到一些奇怪的事情。缓冲区正在解析,而comport devicename仍然是“字符串”并不重要。明天我将调试和玩更多的东西,我唯一一个有comport的桌面拒绝为远程调试器打开端口,可能是因为旧的防病毒安装太糟糕了。我不喜欢新的tcompont的方向,即将基本上是ascii数据转换为Unicode数据。我自己将XE的相关定义添加到了.inc中。但无论如何,对于这个专业来说,这并不重要,明天我将用更新的代码进行测试。最初我更希望在正确的轨道上进行投票,并且在线程中进行投票是一种严重的可能性(在comport3版本中不是幸运的机会)。我将使用较新的版本进行测试。我同意您对最新的4.x分支使用UnicodeString的看法,这种方式我不喜欢用于com端口。有一个版本不是最新的,它仍然比你的beta版要好。IE活动确实有效。