是的 :-)
使用短字符串或pChars
{$WARNINGS ON}
function Test: String;
var
p: pChar;
d: double;
begin
Result := p + FloatToStr(d);
end;
重要提示
普通的 Delphi 字符串和短字符串会自动初始化为空字符串 ''。短字符串存在于栈中,不需要清理。其他字符串是所谓的“托管”类型,在使用引用计数自动删除时不再使用。
PChars 的好消息
pChars 只是指针,Delphi 不会管理它们。
但是 Delphi 会自动将它们转换为字符串,反之亦然。
PChars 的坏消息
如果你将 pChar 转换为字符串,Delphi 将 pChar 的内容复制到字符串中,你仍然需要销毁 pChar。
此外,请注意,这种复制需要时间,如果你经常这样做,会减慢代码速度。
如果你将字符串转换为 pChar,Delphi 将给你一个指向字符串所在地址的指针。但是 Delphi 将停止管理该字符串。你仍然可以给字符串赋值,但它将不再自动增长。
来源:http://www.marcocantu.com/epascal/English/ch07str.htm
以下代码将不能按预期工作:
procedure TForm1.Button2Click(Sender: TObject);
var
S1: String;
begin
SetLength (S1, 100);
GetWindowText (Handle, PChar (S1), Length (S1));
S1 := S1 + ' is the title';
Button1.Caption := S1;
end;
这个程序编译是可以通过的,但是当你运行它时,会有一个惊喜:按钮的标题将具有窗口标题的原始文本,而没有你添加到其中的常量字符串的文本。问题在于当Windows写入字符串(在
GetWindowText
API调用中)时,它没有正确设置长Pascal字符串的长度。Delphi仍然可以使用这个字符串进行输出,并且可以通过寻找空终止符来确定它何时结束,但是如果在空终止符后附加更多字符,则它们将被完全跳过。
我们如何解决这个问题?解决方案是告诉系统将
GetWindowText
API调用返回的字符串转换回Pascal字符串。然而,如果你编写以下代码:
S1 := String (S1);
系统会忽略它,因为将数据类型转换回自身是一项毫无意义的操作。要获取正确的长Pascal字符串,您需要将字符串重新转换为PChar,并让Delphi正确地将其转换回字符串:
S1 := String (PChar (S1));
实际上,您可以跳过字符串转换,因为在Delphi中,PChar到字符串的转换是自动的。这是最终代码:
procedure TForm1.Button3Click(Sender: TObject);
var
S1: String;
begin
SetLength (S1, 100);
GetWindowText (Handle, PChar (S1), Length (S1));
S1 := String (PChar (S1));
S1 := S1 + ' is the title';
Button3.Caption := S1;
end;
另一种方法是通过以下方式重置 Delphi 字符串的长度,使用 PChar 字符串的长度:
SetLength (S1, StrLen (PChar (S1)))
d
被初始化的方式编写的,那么它作为一个人为制造的例子就没有什么意义了! - Disillusioned