13

Delphi 7 のコードを XE4 に移植する作業を行っているので、ここではユニコードを取り上げます。

文字列を TMemoryStream に書き込むメソッドがあるため、この embarcadero の記事によると、文字列の長さ (文字単位) に Char 型のサイズを掛けて、必要な長さ (バイト単位) を取得する必要があります。 length (バイト単位) パラメータを WriteBuffer に渡します。

その前に:

rawHtml : string; //AnsiString
...
memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml);

後:

rawHtml : string; //UnicodeString
...
memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml)* SizeOf(Char));

Delphi の UnicodeString 型についての私の理解では、内部的には UTF-16 です。しかし、Unicode についての私の一般的な理解は、すべての Unicode 文字が 2 バイトでも表現できるわけではなく、一部の特殊な外国文字は 4 バイトかかるということです。Embarcadero の別の記事では、「実際には、1 つの Char が 2 バイトに等しいということは常に正しいとは限りません!」という私の疑念を裏付けているようです。

それで...それはLength(rawHtml)* SizeOf(Char)、一貫して正確であるために本当に十分に堅牢であるかどうか、またはより正確になる文字列のサイズを決定するためのより良い方法があるかどうか疑問に思いますか?

4

4 に答える 4

6

他の人は、UnicodeString のエンコード方法とそのバイト長の計算方法を説明しています。RTLにはすでにそのような機能があることに言及したいだけです - SysUtils.ByteLength()

memorystream1.WriteBuffer(PChar(rawHtml)^, ByteLength(rawHtml));
于 2013-05-14T01:25:10.547 に答える
3

あなたがしていることは正しいです(sizeof(Char)で)。

あなたが参照しているのは、1 つの文字が 1 つのコード ポイントを参照するわけではないということです (たとえば、サロゲート ペアのため)。しかし、文字列内の USC2 でエンコードされた (UTF-16 ではない) 文字は、Length( Str ) * sizeof( Char ).

Delphi で使用される Unicode エンコーディングは、....W バリアントで期待されるすべての Windows API 呼び出しと同じであることに注意してください。

于 2013-05-13T20:44:16.343 に答える