You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Delphi应用迁移至OS X后HID设备西里尔文写入乱码问题

解决Delphi跨OS X迁移后HID设备西里尔文乱码问题

这问题我之前帮同行排查过类似的,核心就是Windows和OS X下Delphi处理字符编码的逻辑差异,尤其是HID设备通信时的编码对齐问题,咱们一步步拆解解决:

先搞懂现象背后的本质

你提到的两个关键现象已经点明了问题:

  • Windows下直接写'Новый комплекс 1'设备正常显示;
  • 复制后变成的'Íîâûé êîìïëåêñ 1'(这其实是UTF-8解码Windows-1251西里尔文的“伪乱码”),设备依然能识别。

这说明你的HID设备只认Windows-1251编码的字节流——不管上层字符串看起来是什么样,只要最终发送的字节是Windows-1251对应的,设备就能正确解析。

OS X下的问题根源

在Windows上,Delphi的AnsiString默认会跟随系统区域(俄语区就是Windows-1251),所以直接转字节发送时,刚好匹配设备的要求。但到了OS X:

  • Delphi的String类型是UTF-16编码;
  • 如果你直接把字符串转成字节流发送,Delphi跨平台框架默认会用UTF-8编码转换,这就导致发送给设备的字节和Windows下完全不一样,设备自然显示乱码。

解决方案:强制编码对齐

我们需要显式把字符串转换成Windows-1251编码的字节数组,再发送给HID设备,以下是可直接复用的Delphi跨平台代码:

uses
  System.SysUtils, System.NetEncoding;

// 将字符串转换为Windows-1251编码的字节数组
function StringToWin1251Bytes(const S: string): TBytes;
var
  Win1251Encoding: TEncoding;
begin
  // 获取Windows-1251编码实例(编码ID为1251)
  Win1251Encoding := TEncoding.GetEncoding(1251);
  try
    Result := Win1251Encoding.GetBytes(S);
  finally
    Win1251Encoding.Free;
  end;
end;

// 调用示例:发送西里尔文到HID设备
procedure SendCyrillicToHID(const CyrillicStr: string);
var
  SendBytes: TBytes;
begin
  SendBytes := StringToWin1251Bytes(CyrillicStr);
  // 替换成你实际的HID设备写入函数
  // YourHIDWriteFunction(SendBytes, Length(SendBytes));
end;

额外验证步骤

为了确保万无一失,你可以:

  • 在Windows下调试时,抓取发送给设备的字节十六进制值;
  • 在OS X下用上面的函数转换后,输出字节的十六进制值,对比两者是否完全一致。
    如果字节完全相同,设备肯定能正常显示西里尔文。

内容的提问来源于stack exchange,提问作者artemk

火山引擎 最新活动