我经常读到编译器在转换为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
?
答案 0 :(得分:11)
流程如下:
s
的长度大于零,则PChar(s)
将返回指向字符串内容的第一个元素的指针。由于string
被设法拥有隐藏 null-terminator,因此无需再进行任何操作。s
的长度为零,则PChar(s)
将返回指向包含空终止符的内存块的指针。作为实现细节,从PChar(nil)
返回的空终止符是在已编译模块的只读部分中分配的全局常量。
Delphi字符串是否自动分配,并且使用隐式#0 char保持为一个char更长,以便更容易地向PChar(PAnsiChar / PWideChar)进行转换?
是
如果可以称之为魔术,那就是:
PChar()
会返回指向空终止符的指针。答案 1 :(得分:3)
内部的字符串变量是指向包含前缀,字符和空终止符的结构的指针。虽然结构从前缀(包含字符串长度,引用计数,字符大小和代码页)开始,但指针指向第一个字符,因此转换为PChar非常简单。
字符串背后的魔力 - &gt;即使字符串为空(PChar(S) <> nil
和S = ''
),PChar强制始终为Pointer(S) = nil
。与Pointer(S)
一样,PChar(S)
调用一个函数来检查Pointer(S)
是否为nil,而Pointer(S) = nil
是否返回指向a nil
的指针,而不是按原样返回字符串变量指针。虚空字符串而不是{{1}}(即指向虚空字符串的空终止符的指针)。