类型不兼容:PAnsiChar和PWideChar,因为StrAlloc返回PWideChar而非StrAlloc所需的PAnsiChar。

3

我知道这可能很简单,但有时Unicode问题会让我很困扰,需要考虑太多细节。

我有以下代码:

pcBuffer := StrAlloc(Stream.Size + 1) where pcBuffer is defined as PWideChar

组件现在需要pcBuffer作为PAnsiChar,所以如果我这样做,我会得到以下错误:

StrAlloc- Incompatible Types PAnsiChar and PWideChar

因为StrAlloc返回的是PWideChar。

我该怎么解决?

我可以直接将其强制转换为PAnsiChar或以Unicode方式分配它,或者通过GetMem进行分配吗?

2个回答

4
在Delphi XE中,SysUtils单元定义了以下函数:
function AnsiStrAlloc(Size: Cardinal): PAnsiChar;
function WideStrAlloc(Size: Cardinal): PWideChar;
function StrAlloc(Size: Cardinal): PChar;

你应该调用 AnsiStrAlloc 来分配一个 PAnsiChar。它接收以字符为单位的 Size。你必须考虑空终止符。
var
  pcBuffer: PAnsiChar;
....
pcBuffer := AnsiStrAlloc(Stream.Size + 1);

然而,这些函数应该被视为已弃用。在Delphi的后续版本中已经有文档记录了这一点。相反,您应该使用AnsiString,让编译器管理生命周期和内存分配。

var
  str: AnsiString;
  pcBuffer: PAnsiChar;
....
SetLength(str, Stream.Size);
pcBuffer := PAnsiChar(str);

缓冲区的生命周期由编译器管理,就像任何 Delphi 字符串变量一样。

上面的代码很可能不是解决您实际问题的最佳方式。没有看到更多细节,很难确定最佳解决方案。我唯一相当有把握的是,StrAlloc 和相关函数并不是前进的方法。


@Shanand 通过让字符串离开作用域、将其设置为''或调用Finalize等方法来处理字符串。显然,您可以使用任何函数,甚至是已弃用的函数。奇怪的是,您接受了一个看起来错误的答案,尽管在细节上有所不同,并提到了在标记版本XE中无法编译的代码。您没有使用XE吗?您的评论非常令人困惑。很烦人,因为我们付出了努力来回答问题,却发现问题关键细节错误。我相信Remy会及时修复他答案中的代码。 - David Heffernan
大卫:抱歉..我错误地勾选了错误的答案..但至少我已经将问题缩小到使用-AnsiStrings.AnsiStrAlloc(Stream.Size + 1),正如Remy建议的那样;然后由您进行了更正。由于您在Remy下发表了评论,所以我选择了那个答案。相反,我对您对他的评论的回复感到满意,这对我很有帮助。我认为我的问题非常清楚,您回答得很正确,感谢您的帮助!我肯定会在未来需要您的帮助。 - Shanand c
现有的D2007代码需要在XE6中重写(这是问题)。无论如何,问题已解决,我正在处理其他问题。谢谢David和Remy。 - Shanand c

2
你正在调用来自SysUtils单元的StrAlloc(),它会分配PWideChar
要分配PAnsiChar,请从AnsiStrings单元调用StrAlloc()
uses
  ..., AnsiStrings;

pcBuffer := AnsiStrings.StrAlloc(Stream.Size + 1);

据我所知,从来没有叫做 AnsiStrings.StrAlloc 的东西。你可能在想的是 AnsiStrings.AnsiStrAlloc。但问题标记为 XE,甚至连 AnsiStrings.AnsiStrAlloc 也不存在。在 XE 中,该函数为 SysUtils.AnsiStrAlloc - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接