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

Delphi Berlin 10.1 OS X app Decode cyrillic for writing to hardDevice

我有 delphi 应用程序,我需要为 OS X 重写它。 此应用 writes/reads 数据 to/from 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 + #
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], #, #0, [rfReplaceAll,   rfIgnoreCase]));

然后写入设备。

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

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

在mac上我成功得到了相同的字符串。但设备无法以西里尔字母显示此内容。

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

话虽如此,如果您有一个以特定字符集编码的字节数组,您可以使用 Delphi 的 TEncoding.Convert() method. You can use the TEncoding.GetEncoding() method to get a TEncoding 特定字符集对象将其转换为另一个字符集(如果不同于标准支持的字符集 - ANSI、ASCII、UTF-7、UTF-8 和 UTF-16 - 它们在 TEncoding).

中有自己的 属性 getter
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);

接下来就是答案了。 Delphi 柏林 10.1 使用 KOI8-R,我的设备 - cp1251。 因为我想写俄语符号(西里尔文),所以我已经为 KOI8-R 和 cp1251 中的符号创建了 table 个匹配项。

所以,我在 KOI8-R 中使用字符串,在 cp1251 中使用它。

简单代码:

 Dict:=TDictionary<String,String>.Create;
 Dict.Add(#9,#$E9);//'й'
 Dict.Add(#E,#$FE);//'ю'
 Dict.Add(#0,#$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;