PChar / PWideChar / PAnsiChar演员阵容中是否有编译器魔法?

时间:2013-02-20 13:20:42

标签: string delphi pointers casting

我经常读到编译器在转换为PChar时会产生某种魔力。

PChar的主要目的是在库中调用外部代码,这些代码期望一个零终止的字符数组(C样式为“string”)。

PChar是一种类型,它是Unicode Delphi上PWideChar的别名,是非unicode Delphi上PAnsiChar的别名。

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

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

2 个答案:

答案 0 :(得分:11)

流程如下:

  • 如果字符串s的长度大于零,则PChar(s)将返回指向字符串内容的第一个元素的指针。由于string被设法拥有隐藏 null-terminator,因此无需再进行任何操作。
  • 如果字符串s的长度为零,则PChar(s)将返回指向包含空终止符的内存块的指针。

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

  

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

如果可以称之为魔术,那就是:

  1. 对空字符串使用PChar()会返回指向空终止符的指针。
  2. Delphi在字符串的末尾维护隐藏的 null-terminator。

答案 1 :(得分:3)

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

字符串背后的魔力 - &gt;即使字符串为空(PChar(S) <> nilS = ''),PChar强制始终为Pointer(S) = nil。与Pointer(S)一样,PChar(S)调用一个函数来检查Pointer(S)是否为nil,而Pointer(S) = nil是否返回指向a nil的指针,而不是按原样返回字符串变量指针。虚空字符串而不是{{1}}(即指向虚空字符串的空终止符的指针)。