1

我经常读到编译器在转换为PChar.

的主要目的PChar是调用库中的外部代码,这些库需要一个以零结尾的字符数组(C 风格的“字符串”)。

PCharPWideCharUnicode Delphi 上的别名和PAnsiChar非 Unicode Delphi 上的别名的类型。

另一方面, Delphi 字符串(string= AnsiString/ UnicodeString,我不是在WideString这里谈论,更不用说......)具有隐藏长度而不是终止字符。ShortString它们也被引用计数并在写入时使用复制。

Delphi 字符串是否自动分配并使用隐式 #0 字符保持一个字符长,以便更轻松地转换为PChar(PAnsiChar / PWideChar) 还是编译器在遇到转换时检查和调整字符串PChar

4

2 回答 2

11

过程如下:

  • 如果字符串s的长度大于零,则PChar(s)返回指向字符串内容的第一个元素的指针。因为string管理有一个隐藏的空终止符,所以不需要做更多的事情。
  • 如果字符串s的长度为零,则PChar(s)返回指向包含空终止符的内存块的指针。

作为实现细节,从中返回的空终止符是PChar(nil)在已编译模块的只读部分中分配的全局常量。

Delphi 字符串是否自动分配并使用隐式 #0 字符保持一个字符长,以便更轻松地转换为 PChar(PAnsiChar / PWideChar)?

是的。

如果你可以这么说的话,神奇之处在于:

  1. 在空字符串上使用PChar()会返回一个指向空终止符的指针。
  2. Delphi在字符串末尾保留隐藏的空终止符。
于 2013-02-20T13:27:19.697 回答
3

字符串变量内部是指向包含前缀、字符和空终止符的结构的指针。虽然结构从前缀开始(包含字符串长度、引用计数、字符大小和代码页),但指针指向第一个字符,因此转换为 PChar 很简单。

string -> PChar 强制转换的神奇之处在于PChar(S) <> nil,即使 string 为空(S = ''and Pointer(S) = nil),也总是如此。不是像Pointer(S)do那样返回一个字符串变量指针'as is',而是PChar(S)调用一个检查是否Pointer(S)为 nil 的函数,如果Pointer(S) = nil返回一个指向虚拟空字符串nil的指针而不是(即指向虚拟空字符串的空终止符的指针)。

于 2013-02-20T14:08:01.323 回答