THandleStream.Create with INVALID_HANDLE_VALUE 无法编译
以下代码用于使用 Delphi 2007 进行编译:
constructor TMyFile.Create(const _Filename: string);
begin
inherited Create(Integer(INVALID_HANDLE_VALUE)));
// ...
end;
在 Delphi XE 中,它失败并出现错误 E1012:常量表达式违反子范围边界。
的声明
原因是 THandleStream.Create: Delphi 2007:
constructor THandleStream.Create(AHandle: Integer);
Delphi XE2:
constructor THandleStream.Create(AHandle: THandle);
,
type
THandle = NativeUInt;
如果我将其更改为
constructor TMyFile.Create(const _Filename: string);
begin
inherited Create(THandle(INVALID_HANDLE_VALUE)));
// ...
end;
It 会在 Delphi XE2 和 Delphi 2007 中编译。 在 Delphi 2007 中,它会导致警告“W1012:常量表达式违反子范围边界”,并且在调用 Delphi 2007 可执行文件时会导致运行时错误。
有什么方法可以更改代码,使其在两个 Delphi 版本中都可以工作,而不必求助于 IFDEFS ?
The following code used to compile with Delphi 2007:
constructor TMyFile.Create(const _Filename: string);
begin
inherited Create(Integer(INVALID_HANDLE_VALUE)));
// ...
end;
In Delphi XE it fails with the error
E1012: Constant expression violates subrange bounds.
The reason is the declaration of THandleStream.Create:
Delphi 2007:
constructor THandleStream.Create(AHandle: Integer);
Delphi XE2:
constructor THandleStream.Create(AHandle: THandle);
with
type
THandle = NativeUInt;
If I change it to
constructor TMyFile.Create(const _Filename: string);
begin
inherited Create(THandle(INVALID_HANDLE_VALUE)));
// ...
end;
It compiles in both, Delphi XE2 and Delphi 2007.
In Delphi 2007 it causes a warning "W1012: Constant expression violates subrange bounds" and it causes a runtime error when the Delphi 2007 executable is called.
Is there any way I can change the code so it works in both Delphi versions without having to resort to IFDEFS ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
THandleStream.Create
将其句柄参数声明为Integer
类型(有符号)。 Delphi XE2 通过将其声明为THandle
(无符号)来改变这一点。我不确定为什么要从签名更改为未签名。显然,对于 64 位目标,它必须扩展到 64 位,但我不确定为什么需要从有符号更改为无符号。据我所知,如果没有条件编译,就无法解决这个问题。
您可以通过声明这样的类型来包含损坏:
然后在您的调用站点上您将编写
注意,条件
XE2_OR_ABOVE
不存在,您必须计算出真正的条件应该是什么。THandleStream.Create
declares its handle parameter as being of typeInteger
(signed). Delphi XE2 changes this by declaring it asTHandle
(unsigned). I'm not sure why this change from signed to unsigned was made. Clearly it had to be widened to 64 bit for 64 bit targets but I'm not sure why the change from signed to unsigned needed to be made.So far as I can tell, there is no way to get around this problem without conditional compilation.
You could contain the damage by declaring a type like this:
Then at your call sites you would write
Note that the conditional
XE2_OR_ABOVE
does not exist and you'll have to work out what the condition really should be.