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; 
4

2 に答える 2

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;

ただし、すべてが必要なわけではありません。Delphi が文字列変換を実行します。

function UTF8FromUTF16_2(sUTF16: UnicodeString): UTF8String;
begin
  Result := sUTF16;
end;
于 2012-05-12T07:09:51.707 に答える
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+ では、はるかに単純なアプローチがあります。

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

さらに簡単なことに、バイトではなく文字列を扱う場合は、単に aWideStringまたは a UnicodeString(どちらも UTF-16 でエンコードされています) を aに割り当てUTF8String、RTL に変換を処理させることができます。

于 2012-05-13T03:44:55.527 に答える