うーん、なぜそんなことをしているのですか?WideString に再度格納するためだけに、WideString を UTF-8 にエンコードするのはなぜですか。明らかに、Windows API の Unicode バージョンを使用しています。したがって、UTF-8 でエンコードされた文字列を使用する必要はありません。それとも私は何かを逃していますか。
Windows API 関数は Unicode (2 バイト) または ANSI (1 バイト) であるためです。UTF-8 は、主に 1 文字あたり 1 バイトを含むため、ここでは間違った選択になりますが、ASCII ベースより上の文字では 2 バイト以上を使用します。
それ以外の場合、Unicode Delphi の古いコードに相当するものは次のようになります。
var
UnicodeStr: string;
UTF8Str: string;
begin
UnicodeStr:='some unicode text';
UTF8Str:=UTF8Encode(UnicodeStr);
Windows.SomeFunction(PWideChar(UTF8Str), ...)
end;
WideString と文字列 (UnicodeString) は似ていますが、新しい UnicodeString は参照カウントされ、WideString はそうでないため、より高速です。
UTF-8 文字列は 1 文字あたりのバイト数が可変であるため、コードは正しくありません。「A」は 1 バイトとして格納されます。ただのASCIIバイトコード。一方、「ü」は 2 バイトとして格納されます。また、PWideChar を使用しているため、関数は常に 1 文字あたり 2 バイトを想定しています。
別の違いがあります。古いバージョンの Delphi (ANSI) では、Utf8String は単なる AnsiString でした。Delphi の Unicode バージョンでは、Utf8String は背後に UTF-8 コード ページを持つ文字列です。そのため、動作が異なります。
古いコードはまだ正しく動作します:
var
UnicodeStr: WideString;
UTF8Str: WideString;
begin
UnicodeStr:='some unicode text';
UTF8Str:=UTF8Encode(UnicodeStr);
Windows.SomeFunction(PWideChar(UTF8Str), ...)
end;
Delphi 2007 と同じように動作します。そのため、別の場所で問題が発生している可能性があります。
ミックあなたは正しいです。コンパイラは、バックグラウンドで追加の作業を行います。したがって、これを回避するには、次のようにします。
var
UTF8Str: AnsiString;
UnicodeStr: WideString;
TempString: RawByteString;
ResultString: WideString;
begin
UnicodeStr := 'some unicode text';
TempString := UTF8Encode(UnicodeStr);
SetLength(UTF8Str, Length(TempString));
Move(TempString[1], UTF8Str[1], Length(UTF8Str));
ResultString := UTF8Str;
end;
確認しましたが、同じように動作します。メモリ内でバイトを直接移動するため、バックグラウンドでコードページ変換が行われません。もっと優雅にできると確信していますが、要点は、これがあなたが達成したいことへの道であると私が見ているということです.