Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos Delphi-将字符串从UTF-8转换回_Macos_Delphi_Utf 8 - Fatal编程技术网

Macos Delphi-将字符串从UTF-8转换回

Macos Delphi-将字符串从UTF-8转换回,macos,delphi,utf-8,Macos,Delphi,Utf 8,我在将UTF-8编码字符串转换回delphi可用的内容时遇到问题。 该应用程序是用XE8编写的,正在windows和OSX上部署。该应用程序分别在windows和OSX上使用LimeLM API dll和dylib库。 在windows上一切正常,我遇到的问题是转换OSX上的动态库返回的字符串。我很欣赏所有进出动态库的字符串都需要UTF-8编码。 limeLM函数返回一个PWideChar值,我假设它是UTF编码的。但是,我使用哪个函数尝试将值转换为Delphi中可用的值并不重要,我得到的只是垃

我在将UTF-8编码字符串转换回delphi可用的内容时遇到问题。 该应用程序是用XE8编写的,正在windows和OSX上部署。该应用程序分别在windows和OSX上使用LimeLM API dll和dylib库。 在windows上一切正常,我遇到的问题是转换OSX上的动态库返回的字符串。我很欣赏所有进出动态库的字符串都需要UTF-8编码。 limeLM函数返回一个PWideChar值,我假设它是UTF编码的。但是,我使用哪个函数尝试将值转换为Delphi中可用的值并不重要,我得到的只是垃圾

以下是函数:

class function TurboActivate.GetFeatureValue(featureName: String): String;
var
    value : PWideChar;
    FieldName : PWideChar;
    tmpStr : String;
begin

    {$IFDEF MSWINDOWS}
    FieldName := PwideChar(featureName);
    {$ENDIF}
    {$IFDEF MACOS}
    FieldName := PWideChar(UTF8Encode(featureName));
    {$ENDIF}


    value := GetFeatureValue(FieldName, nil);

    if (value = '') then
    begin
        raise ETurboActivateException.Create('Failed to get feature value.  the feature doesn''t exist.');
    end;
    {$IFDEF MSWINDOWS}
    Result := value;
    {$ENDIF}
    {$IFDEF MACOS}
    tmpStr :=  UTF8ToString(value);
    ShowMessage(tmpStr);
    tmpStr :=  UTF8ToWideString(value);
    ShowMessage(tmpStr);
    tmpStr :=  UTF8ToUnicodeString(value);
    ShowMessage(tmpStr);
    tmpStr :=  UTF8ToAnsi(value);
    ShowMessage(tmpStr);

    Result := TmpStr;
    {$ENDIF}

end; 
这肯定有一个解码的价值, 价值观散汤湡獤杀潯汧浥楡⹬潣M䌴䅓㜭䙇ⵊ䵙㑗㈭呖ⵆ䥉儵䈭呎́"4

但tmpStr总是包含“??”c??????/”

任何帮助都将不胜感激

价值观散汤湡獤杀潯汧浥楡⹬潣M䌴䅓㜭䙇ⵊ䵙㑗㈭呖ⵆ䥉儵䈭呎́"4

这表示您在解释8位文本,可能是UTF-8编码的,就像它是UTF-16编码的一样。一般来说,当您看到带有中文字符的UTF-16字符串时,要么是正确解释的中文文本,要么是错误解释的8位文本

当您将该文本正确解释为UTF-8时,它是:

cedlands@googlemail.com 4CSA-7GFJ-YMW4-2VTF-II5Q-BNTA♥♦
我通过这个代码得到:

  Writeln(TEncoding.UTF8.GetString(
    TEncoding.Unicode.GetBytes('散汤湡獤杀潯汧浥楡⹬潣m䌴䅓㜭䙇ⵊ䵙㑗㈭呖ⵆ䥉儵䈭呎́'#4)));
但是请注意,如果查看
TEncoding.Unicode.GetBytes('散汤湡獤杀潯汧浥楡⹬潣M䌴䅓㜭䙇ⵊ䵙㑗㈭呖ⵆ䥉儵䈭呎́'#4)
然后您将看到它包含一个空值。因此,实际上字符串在电子邮件地址之后以null结尾

问题从这里开始:

value : PWideChar;
....
value := GetFeatureValue(FieldName, nil);
事实上,
GetFeatureValue
返回
PAnsiChar
。有效载荷是UTF-8编码的,假设我对你的解释是正确的

因此,您需要进行以下更改:

  • GetFeatureValue
    的返回类型更改为
    PAnsiChar
  • value
    的类型更改为
    PAnsiChar
  • 使用
    UnicodeFromLocaleChars
    TEncoding.GetString
    value
    转换为字符串
  • 可能是这样的:

    var
      Bytes: TBytes;
    ....
    SetLength(Bytes, StrLen(value));
    Move(value^, Pointer(Bytes)^, Length(Bytes));
    str := TEncoding.UTF8.GetString(Bytes);
    

    现在,对于问题中将
    str
    设置为
    cedlands@googlemail.com
    。如上所述,数据包含一个空终止符,当字符串被错误地解释为UTF-16时,它无法终止字符串。也就是说,文本
    4CSA-7GFJ-YMW4-2VTF-II5Q-BNTA♥♦
    来自缓冲区溢出。

    使用
    TEncoding
    有点懒惰,因为它涉及堆alloc和可以避免的mem拷贝。通过使用UnicodeFromLocaleChars可以避免这种情况,但这只是稍微复杂一点。所以我选择了懒惰的选择!但在生产代码中,我想我会使用
    UnicodeFromLocaleChars
    。或者,您可以使用
    SetString()
    PAnsiChar
    数据复制到
    UTF8String
    变量中,然后将
    UTF8String
    直接分配给
    UnicodeString
    ,并让RTL为您处理转换。