2
var
  S: string;
begin
  SetLength(S, MAX_SIZE);// when casting to a PChar, be sure the string is not empty
  SetLength(S, GetModuleFilename(0, PChar(S), Length(S)));
  // statements
end;

为了消除复制缓冲区的开销,您可以将字符串强制转换为 PChar(如果您确定例程不需要 PChar 保留在内存中)。 http://docwiki.embarcadero.com/RADStudio/en/Passing_a_Local_Variable_as_a_PChar

我们有一个字符串,它会一直保留在内存中,直到它的引用计数减为 0,所以它不会在作用域中被删除。那么,为什么我们需要PChar留在记忆中呢?PChar是否有一些 API 函数需要与之前传递给另一个 API 函数的完全相同的引用?

特别是我正在考虑示例代码。因此,问题必须是“为什么例程需要传递给它的 PChar(字符串的类型转换)在它返回后保留在内存中?”。异步 i/o 例程,或在调用者返回后访问传递的 pchar 的异步方法,或由另一个线程修改全局字符串都是很好的理由。

4

1 回答 1

6

有时 API 会将指针存储到以后。例如考虑异步 IO。

或者,如果您编写如下代码,它也会失败:

function Broken():PChar;
var s:string;
begin
  s:=IntToStr(Random(100));//no string constant
  return PChar(s);
end;

重要的一点是,如果您将 refcount>1 的字符串转换为PChar,它将创建一个副本,然后将 refcount=1 的字符串交给您。因此PChar,一旦您传入的 s 变得无效,即使它的 refcount>1,您也将变得无效。

另一个破碎的例子:

var p:PChar;
var s:string;

s := IntToStr(Random(100));//no string constant
p := PChar(s);
s := "ABC";
DoSomething(p);//p is invalid by now
于 2012-02-08T14:06:36.667 回答