2012-05-12 31 views
0
Public Function UTF8FromUTF16(ByRef abytUTF16() As Byte) As Byte() 

    Dim lngByteNum As Long 
    Dim abytUTF8() As Byte 
    Dim lngCharCount As Long 

    On Error GoTo ConversionErr 

    lngCharCount = (UBound(abytUTF16) + 1) \ 2 
    lngByteNum = WideCharToMultiByteArray(CP_UTF8, 0, abytUTF16(0), _ 
     lngCharCount, 0, 0, 0, 0) 

    If lngByteNum > 0 Then 
     ReDim abytUTF8(lngByteNum - 1) 
     lngByteNum = WideCharToMultiByteArray(CP_UTF8, 0, abytUTF16(0), _ 
      lngCharCount, abytUTF8(0), lngByteNum, 0, 0) 
     UTF8FromUTF16 = abytUTF8 
    End If 

    Exit Function 

ConversionErr: 
    MsgBox " Conversion failed " 

End Function 

var 
    abytUTF8 : array of Byte; // Global 

function UTF8FromUTF16(sUTF16 : WideString) : pAnsiChar; 
var 
    lngByteNum : integer; 
    lngCharCount : integer; 
begin 
    // On Error GoTo ConversionErr 
    result := nil; 

    lngCharCount := Length(sUTF16); 
    lngByteNum := WideCharToMultiByte(CP_UTF8, 0, @sUTF16[1], 
     lngCharCount, nil, 0, nil, nil); 

    If lngByteNum > 0 Then 
    begin 
     SetLength(abytUTF8, lngByteNum+1); 
     abytUTF8[lngByteNum] := 0; 
     lngByteNum := WideCharToMultiByte(CP_UTF8, 0, @sUTF16[1], 
      lngCharCount, @abytUTF8[0], lngByteNum, nil, nil); 
     result := pAnsiChar(@abytUTF8[0]); 
    End; 
End; 
+0

类似:http://stackoverflow.com/questions/259836/what-is-the-best-way-to-convert-tbytes-utf-16-to-a-string – Harriv

+0

虽然我同情你的困境,你至少应该**尝试解释你的问题。以目前的形式,这个问题对其他任何人都没有用,而且期望其他人阅读它并试图猜测你的问题是什么太多了。 (并且试图用英语表达自己,你会提高你的英语技能......如果你将来会在这里提问,你需要做的事情。) –

回答

5

你的代码没有设置所得到的字符串的编码。 Delphi(自Delphi 2009以来)需要ANSI字符串的编码信息,否则使用默认系统区域设置。你的代码的工作版本是:

function UTF8FromUTF16(sUTF16: UnicodeString): UTF8String; 
var 
    lngByteNum : integer; 
    lngCharCount : integer; 
begin 
    Result := ''; 

    lngCharCount := Length(sUTF16); 
    if lngCharCount = 0 then Exit; 

    lngByteNum := WideCharToMultiByte(CP_UTF8, 0, @sUTF16[1], lngCharCount, nil, 0, nil, nil); 
    if lngByteNum > 0 then begin 
    SetLength(Result, lngByteNum); 
    WideCharToMultiByte(CP_UTF8, 0, @sUTF16[1], lngCharCount, @Result[1], lngByteNum, nil, nil); 
    end; 
end; 

不过你不必全部 - 德尔福执行字符串转换为你:

function UTF8FromUTF16_2(sUTF16: UnicodeString): UTF8String; 
begin 
    Result := sUTF16; 
end; 
+0

谢谢你。但做的工作..这个代码UTF16 LE - > UTF8? – user1390537

+0

是的,UTF16在两个函数中都是UTF16-LE。如果您需要使用UTF16-BE,请使用'SysUtils.pas'中的'TEncoding'类。 – kludg

+0

非常感谢你! – user1390537

1

字面翻译就是这个样子:

function UTF8FromUTF16(const abytUTF16: TBytes): TBytes; 
var 
  lngByteNum: LongInt; 
  abytUTF8: TBytes; 
  lngCharCount: LongInt; 
begin 
  Result := nil; 
    lngCharCount := Length(abytUTF16) div 2; 
  lngByteNum := WideCharToMultiByte(CP_UTF8, 0, PWideChar(abytUTF16), lngCharCount, nil, 0, nil, nil); 
  if lngByteNum > 0 then 
    begin 
    SetLength(abytUTF8, lngByteNum); 
    lngByteNum := WideCharToMultiByte(CP_UTF8, 0, PWideChar(abytUTF16), lngCharCount, PAnsiChar(abytUTF8), lngByteNum, nil, nil); 
    Result := abytUTF8; 
    Exit; 
  end; 
    if GetLastError <> 0 then 
    MessageBox(0, ' Conversion failed ', '', MB_OK); 
end; 

在Delphi 2009+,有一个更simplier方法:

function UTF8FromUTF16(const abytUTF16: TBytes): TBytes; 
begin 
    Result := TEncoding.Convert(TEncoding.Unicode, TEncoding.UTF8, abytUTF16); 
end; 

更容易,如果您使用字符串而不是字节,那么您可以简单地将WideStringUnicodeString(均为UTF-16编码)分配给UTF8String,并让RTL为您处理转换。

+0

如何使用功能。? UTF8FromUTF16('Some Text'); <错误 – user1390537

+0

最初的VB代码基于字节数组,而不是字符串。如果你想使用字符串,那么你不需要任何这种代码。正如我所说的,简单使用Delphi的'UnicodeString'和'UTF8String'类型,而不是,并让3(”处理转换,如:'VAR sUtf16:的UnicodeString; sUtf8:UTF8字符串;开始sUtf16:= '一些文本'; sUtf8: = sUtf16; end;' –