Delphi Berlin 10.1 OS X app解码用于写入hardDevice的西里尔语

时间:2018-03-14 17:33:48

标签: macos delphi unicode decode delphi-10.1-berlin

我有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上我成功获得相同的字符串。但是设备无法用西里尔语显示出来。

2 个答案:

答案 0 :(得分:2)

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

话虽这么说,如果你有一个在特定字符集中编码的字节数组,你可以使用Delphi的TEncoding.Convert()方法将它转换为另一个字符集。您可以使用TEncoding.GetEncoding()方法获取特定字符集的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;

更新:要在特定字符集中对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);

答案 1 :(得分: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;