代码之家  ›  专栏  ›  技术社区  ›  artemk

Delphi Berlin 10.1 OS X应用程序解码西里尔文以写入硬件设备

  •  -1
  • artemk  · 技术社区  · 8 年前

    我有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 回复  |  直到 8 年前
        1
  •  2
  •   Remy Lebeau    8 年前

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

    这就是说,如果您有一个字节数组,它编码在一个特定的字符集中,那么您可以使用Delphi的 TEncoding.Convert() 方法您可以使用 TEncoding.GetEncoding() 获取 TEncoding 特定字符集的对象(如果不同于标准支持的字符集(ANSI、ASCII、UTF-7、UTF-8和UTF-16),这些字符集在 十编码 )。

    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);
    
        2
  •  0
  •   artemk    8 年前

    答案是下一个。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;