【问题标题】:THandleStream.Create with INVALID_HANDLE_VALUE does not compile带有 INVALID_HANDLE_VALUE 的 THandleStream.Create 无法编译
【发布时间】:2011-11-04 13:20:03
【问题描述】:

以下代码用于使用 Delphi 2007 进行编译:

constructor TMyFile.Create(const _Filename: string);
begin
  inherited Create(Integer(INVALID_HANDLE_VALUE)));
  // ...
end;

在 Delphi XE 中失败并出现错误 E1012: 常量表达式违反子范围界限。

原因是THandleStream.Create的声明:

德尔福 2007:

constructor THandleStream.Create(AHandle: Integer);

德尔福 XE2:

constructor THandleStream.Create(AHandle: THandle);

type
  THandle = NativeUInt;

如果我把它改成

constructor TMyFile.Create(const _Filename: string);
begin
  inherited Create(THandle(INVALID_HANDLE_VALUE)));
  // ...
end;

它在 Delphi XE2 和 Delphi 2007 中都可以编译。 在 Delphi 2007 中,它会导致警告“W1012:常量表达式违反子范围界限”,并且在调用 Delphi 2007 可执行文件时会导致运行时错误。

有什么方法可以更改代码,使其在两个 Delphi 版本中都可以工作,而不必求助于 IFDEFS 吗?

【问题讨论】:

  • @David,这比评论更重要;)
  • @TLama 看过旧 Delphi 版本中 THandleStream.Create 的声明后,我现在明白了这个问题。

标签: delphi delphi-2007 delphi-xe2


【解决方案1】:

THandleStream.Create 将其句柄参数声明为Integer(有符号)类型。 Delphi XE2 通过将其声明为THandle(无符号)来改变这一点。我不确定为什么要进行从已签名到未签名的更改。显然,对于 64 位目标,它必须扩大到 64 位,但我不确定为什么需要进行从有符号到无符号的更改。

据我所知,没有条件编译就无法解决这个问题。

您可以通过声明这样的类型来控制损坏:

type
{$IFDEF XE2_OR_ABOVE}
  THandleCast = THandle;
{$ELSE}
  THandleCast = Integer;
{$ENDIF}

然后在你的呼叫站点你会写

inherited Create(THandleCast(INVALID_HANDLE_VALUE)));

请注意,条件 XE2_OR_ABOVE 不存在,您必须弄清楚条件到底应该是什么。

【讨论】:

  • 谢谢大卫。我担心我不得不使用 cond。汇编。我在所有单位中都使用 jedi.inc,因此只需检查 {$IFDEF DELPHIXE2_UP}。
  • @David,你可以使用$IFDEF VER230 或者更好的$IF CompilerVersion >= 23
  • @tlama 是的,我知道这一点,但我也知道每个人对此都有不同的偏好
  • 这更可能是RTLVersion >= 23 而不是CompilerVersion
  • 因为看起来没有其他人有更好的建议,我接受你的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 2023-04-04
  • 1970-01-01
  • 2013-10-06
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多