1

コンパイラがにキャストするときに、ある種の魔法を実行することをよく読みますPChar

の主な目的はPChar、ゼロで終了する文字配列(Cスタイルの「文字列」)を期待するライブラリ内の外部コードを呼び出すことです。

PCharPWideCharUnicode Delphiではのエイリアスであり、PAnsiChar非UnicodeDelphiではのエイリアスであるタイプです。

一方、 Delphi文字列(string= AnsiString/ 、ここでUnicodeStringは話していませんが、 ...は言うまでもありません)には、終了文字ではなく非表示の長さがあります。また、参照カウントされ、コピーオンライトを使用します。WideStringShortString

PChar(PAnsiChar / PWideChar)へのキャストを容易にするために、Delphi文字列は自動的に割り当てられ、暗黙の#0文字で1文字長く保たれますか、またはコンパイラは、への変換が発生したときに文字列をチェックして調整しPCharますか?

4

2 に答える 2

11

プロセスは次のとおりです。

  • 文字列のs長さがゼロより大きい場合、PChar(s)文字列コンテンツの最初の要素へのポインタを返します。は非表示stringのヌルターミネータを持つように管理されているため、これ以上何もする必要はありません。
  • 文字列のs長さがゼロの場合PChar(s)、nullターミネータを含むメモリブロックへのポインタを返します。

実装の詳細として、から返されるnullターミネータはPChar(nil)、コンパイルされたモジュールの読み取り専用セクションに割り当てられたグローバル定数です。

PChar(PAnsiChar / PWideChar)へのキャストを容易にするために、Delphi文字列は自動的に割り当てられ、暗黙の#0文字で1文字長く保たれますか?

はい。

あなたがそれをそれと呼ぶことができるならば、魔法はそれです:

  1. 空の文字列で使用PChar()すると、nullターミネータへのポインタが返されます。
  2. Delphiは、文字列の最後に非表示のnullターミネータを保持します。
于 2013-02-20T13:27:19.697 に答える
3

文字列変数は、内部的には、プレフィックス、文字、およびnullターミネータを含む構造体へのポインタです。構造はプレフィックス(文字列の長さ、参照カウント、文字サイズ、コードページを含む)から始まりますが、ポインターは最初の文字を指しているため、PCharへのキャストは簡単です。

PChar(S) <> nil文字列->PCharキャストの背後にある魔法は、文字列が空(S = ''および)であっても、常に、ということですPointer(S) = nil。文字列変数ポインタを「そのまま」返す代わりに、Pointer(S)doのように、がnilでPChar(S)あるかどうかをチェックし、ifが代わりにダミーの空の文字列へのポインタ(つまり、ダミーの空の文字列のnullターミネータへのポインタ)を返す関数を呼び出します。Pointer(S)Pointer(S) = nilnil

于 2013-02-20T14:08:01.323 に答える