我想在旧版和新版Delphi中使用某些单元。从最近的Delphi版本开始,Utf8Decode
抛出一个已弃用的警告,建议切换到Utf8ToString
。问题是旧版本的Delphi没有声明这个函数,所以我应该使用哪个{$IFDEF}
标签来定义名为Utf8Decode
{或者Utf8String
的{{1}}的包装器?
或换句话说:Utf8ToWideString
引入了哪个版本?
答案 0 :(得分:6)
我想我会用$IF
来实现它,这样调用代码就可以使用新的RTL函数,或者使用旧的弃用版本。由于新的UTF8ToString
返回一个UnicodeString,我认为可以安全地假设它是在Delphi 2009中引入的。
{$IF not Declared(UTF8ToString)}
function UTF8ToString(const s: UTF8String): WideString;
begin
Result := UTF8Decode(s);
end;
{$IFEND}
答案 1 :(得分:2)
据我记得:
UTF8String
和相关的UTF8Encode / UTF8Decode
; UTF8ToWideString
和UTF8ToString
在Delphi 2009(即Unicode版本)中引入,如下:
function UTF8Decode(const S: RawByteString): WideString;
deprecated 'Use UTF8ToWideString or UTF8ToString';
为了解决此兼容性问题,您可以定义自己的UTF8ToString
函数(如David建议的那样),也可以使用自己的实现。
我为我们的框架改写了一些(也许)更快的版本,它也适用于Delphi 5(我想为一些传统的Delphi 5代码添加UTF-8支持,大约3,000,000个带有第三方组件的源代码行停止轻松升级 - 至少是经理的决定)。查看SynCommons.pas中的所有相应RawUTF8
类型:
{$ifdef UNICODE}
function UTF8DecodeToString(P: PUTF8Char; L: integer): string;
begin
result := UTF8DecodeToUnicodeString(P,L);
end;
{$else}
function UTF8DecodeToString(P: PUTF8Char; L: integer): string;
var Dest: RawUnicode;
begin
if GetACP=CODEPAGE_US then begin
if (P=nil) or (L=0) then
result := '' else begin
SetLength(Dest,L); // faster than Windows API / Delphi RTL
SetString(result,PAnsiChar(pointer(Dest)),UTF8ToWinPChar(pointer(Dest),P,L));
end;
exit;
end;
result := '';
if (P=nil) or (L=0) then
exit;
SetLength(Dest,L*2);
L := UTF8ToWideChar(pointer(Dest),P,L) shr 1;
SetLength(result,WideCharToMultiByte(GetACP,0,pointer(Dest),L,nil,0,nil,nil));
WideCharToMultiByte(GetACP,0,pointer(Dest),L,pointer(result),length(result),nil,nil);
end;
{$endif}