Delphi Berlin 10.1 OS X 应用解码西里尔字母以写入 hardDevice

问题描述 投票:0回答:2

我有 delphi 应用程序,我需要为 OS X 重写它。 此应用程序向/从 HID 设备写入/读取数据。

我在尝试从 mac 写入字符串时遇到问题。

这是我正在写的行(来自 Windows 上的调试器):'Новый комплекс 1' 这很好用。同时,如果将其从调试器复制到某个地方,它会变成“Íîâûé êîìïëåêñ 1”。设备以西里尔文原样显示它。没关系。

当我尝试在 OS X 上重复此步骤时,设备显示无法读取的符号。但是,如果我从 Windows 示例中对 'Íîâûé êîìïëåêñ 1' 进行硬编码,它又可以了。

给一些提示。

如何在 Windows 上运行

一些代码:

 s:= 'Новый комлекс 1'

s:= AnsiToUtf8(ReplaceNull(s));

这里是 ReplaceNULL:

function ReplaceNull(const Input: string): string;
var
Index: Integer;
Res: String;
begin
Res:= '';
for Index := 1 to Length(Input) do
begin
if Input[Index] = #0 then
  Res:= Res + #$12
else
  Res:= Res + Input[Index];
end;
 ReplaceNull:= Res;
end;

我把这个字符串放到 Tstringlist 然后保存到文件:

ProgsList.SaveToFile(Mwork.pathLibs+'stream.ini', TEncoding.UTF8);

其他程序读取这个列表然后写入设备:

Progs:= TStringList.Create();

Progs.LoadFromFile(****);

s:= UTF8ToAnsi(stringreplace(Progs.Strings[i], #$12, #0, [rfReplaceAll,   rfIgnoreCase]));

然后写入设备。

所以写的那一行看起来是这样的:

"'þ5'#0'ÿ'#$11'Новый комплекс 1'#0'T45/180;55;70;85;90;95;100;T45/180'#0'ÿ'"

在 Mac 上我成功地得到了相同的字符串。但是设备无法用西里尔文显示。

macos delphi unicode decode delphi-10.1-berlin
2个回答
2
投票

Delphi

string
在所有平台上都以 UTF-16 编码。无需转换它,除非您在应用程序外部与非 Unicode 数据进行交互。

话虽如此,如果您有一个以特定字符集编码的字节数组,您可以使用 Delphi 的

TEncoding.Convert()
方法将其转换为另一个字符集。您可以使用
TEncoding.GetEncoding()
方法获取特定字符集的
TEncoding
对象(如果不同于标准支持的字符集 - ANSI、ASCII、UTF-7、UTF-8 和 UTF-16 - 这在
TEncoding
).

中有自己的财产获取者
var
  SrcEnc, DstEnc: TEncoding;
  SrcBytes, ConvertedBytes: TBytes;
begin
  SrcBytes := ...; // Cyrillic encoded bytes
  SrcEnc := TEncoding.GetEncoding('Cyrillic'); // or whatever the real name is...
  try
    DstEnc := TEncoding.GetEncoding('Windows-1251');
    try
      ConvertedBytes := TEncoding.Convert(SrcEnc, DstEnc, SrcBytes);
    finally
      DstEnc.Free;
    end;
  finally
    SrcEnc.Free;
  end;
  // use ConvertedBytes as needed...
end;

Update:要在特定字符集中编码 Unicode 字符串,只需调用

TEncoding.GetBytes()
方法,例如:

s := 'Новый комлекс 1';
Enc := TEncoding.GetEncoding('Windows-1251');
try
  bytes := Enc.GetBytes(s);
finally
  Enc.Free;
end;

s := 'Новый комлекс 1';
bytes := TEncoding.UTF8.GetBytes(s);

您可以使用

TEncoding.GetString()
将特定字符集中的字节解码回字符串,例如:

bytes := ...; // Windows-1251 encoded bytes
Enc := TEncoding.GetEncoding('Windows-1251');
try
  s := Enc.GetString(bytes);
finally
  Enc.Free;
end;

bytes := ...; // UTF-8 encoded bytes
s := TEncoding.UTF8.GetString(bytes);

0
投票

接下来是答案。 Delphi Berlin 10.1 使用 KOI8-R,我的设备是 cp1251。 因为我想写俄罗斯符号(西里尔文),所以我为 KOI8-R 和 cp1251 的符号创建了匹配表。

所以,我把 KOI8-R 中的字符串放在 cp1251 中。

简单代码:

 Dict:=TDictionary<String,String>.Create;
 Dict.Add(#$439,#$E9);//'й'
 Dict.Add(#$44E,#$FE);//'ю'
 Dict.Add(#$430,#$E0);//'а'

....

function tkoitocp.getCP1251Code(str:string):string;
var i:integer; res,key,val:string;  pair:Tpair<String,String>;
begin
res:='';
for i:=1 to length(str) do
 begin
   if dict.ContainsKey(str[i]) then
   begin
      pair:= dict.ExtractPair(str[i]);

      res:=res+pair.Value;
      dict.Add(pair.Key,pair.Value);
   end
   else
   res:=res+str[i];
 end;
 Result:=res;

end;
© www.soinside.com 2019 - 2024. All rights reserved.