【问题标题】:Using the Events in a serial port component TComPort (v4) from a thread in Delphi?在 Delphi 的线程中使用串行端口组件 TComPort (v4) 中的事件?
【发布时间】:2011-12-19 15:16:01
【问题描述】:

几年前,当某个应用必须非常快速地响应某些串行事件时,我将我的一个应用程序的串行处理转移到一个线程中。

它是在 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()

我最近不得不对此进行挖掘,并注意到它在我的具有 tcomport4 的 Delphi XE 中不起作用。在查看源代码时,我看到了以下评论 comport4 改变了它处理其内部线程的方式(“重叠”属性),但默认似乎是“真”有注释“经典”,我

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

注意协议是二进制的,所有的string,char ansistring,ansichar 的改变都和我在普通主线程版本中一样

现在是真正的问题:

  1. 有人让 tcomport4 在线程中工作吗?
  2. 上面有明显的错误吗?
  3. 还是我需要迁移到其他组件?

我仍在调试发生了什么,但我很着急,我在发布此消息时希望快速获得指针。

更新

我重新安装了一个旧的 turbo delphi 副本,并验证它在 v3 中可以正常工作。我在代码路径中修复了一个小错误,它与我的想法有点不同(不是在上面的代码中)

这让我可以更好地描述 dxe/comportv4 和 bds2006/comportv3 之间的行为; v4 代码生成更多的读取事件(数百次/秒)。似乎读取不会从传入队列中删除读取的字符。

更新 2

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

不幸的是,这些更改传播回生产版本(完全编写的协议解码)有点冒险,所以我必须测试中间版本(4.0 和 4.11f 之间)。我会在适当的时候这样做,有什么建议是最后一个 readstr(ansistring) 版本吗?

更新 3

最后,我只是重命名了 4.11f 单元并将它们与旧版本并行使用,将 4.11f 用于线程代码库并使用旧版本来维护现有代码。

从长远来看,我可能会简单地采用 waitforevent 代码并制作自己的版本。它的主要问题是无法查看等待是否在超时、停止事件或其他情况下终止。这意味着您需要另一个计时器,例如定期发送。

【问题讨论】:

  • TComPort 的确切版本是什么? (在各种 4.x 版本中存在很多差异和许多不同的奇怪错误。)
  • 4.0 带有字符串“W.Postma 为 Delphi 2009 修复。2008 年 10 月”。 Afaik 我在 2009 年夏天在一个名为“tcomport4beta”的档案中得到它
  • 那个版本有一些严重的错误。您使用的事件处理代码在 delphi 2009 中几乎无法使用,而在 XE 中则根本无法使用该版本。我会升级到稳定的发布版本。请注意,4.0 和 4.11 的字符串类型有所不同。从您发布的代码来看,您似乎没有为您的序列代码选择我使用 AnsiString 的默认路线,所以我建议您迁移到最新的 4.11 版本。
  • 您对 Delphi 2009 年之前和 2009 年之后的 Unicode 问题了解多少? :-) 如您所知,在 Delphi 2006/2007 时代,一个 Char 很容易等于来自 com 端口的一个字节。到目前为止,delphi 中的 Char 是一个 Unicode 实体,虽然 TComPort 还不足以读取两个字节并将其称为“unicode 字符”,但如果您不移植到 Unicode Delphi,您仍然可能会遇到一些奇怪的事情正确。
  • 缓冲区是 ansistring,comport devicename 仍然是“string”没关系。明天我会调试和玩更多,我这里唯一带有 comport 的桌面拒绝为远程调试器打开一个端口,可能是被旧的防病毒安装搞砸了。我不喜欢较新的 tcomports 的方向,基本上将 ascii 数据转换为 unicodestring。我自己将 XE 的相关定义添加到 .inc 中。不过不管怎样,这个专业没关系,我明天用更新的代码测试一下。

标签: delphi tcomport


【解决方案1】:

您需要升级到最新的稳定版 4.11 版本here

【讨论】:

  • 最初我更希望投票是否在正确的轨道上,并且在线程中进行投票是一种严重的可能性(在 comport3 版本中不是幸运的机会)。我将使用较新的版本进行测试
  • 我同意你关于使用 UnicodeString 的最新 4.x 分支的看法,这种方式我不喜欢 com 端口。有一个版本不是最新的,它仍然比您拥有的测试版更好。 IE 事件确实有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多