THandleStream.Create с INVALID_HANDLE_VALUE не компилируется - PullRequest
3 голосов
/ 04 ноября 2011

Следующий код, используемый для компиляции с 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;

Он компилируется в Delphi XE2 и Delphi 2007. В Delphi 2007 это вызывает предупреждение «W1012: выражение константы нарушает границы поддиапазона» и вызывает ошибку времени выполнения при вызове исполняемого файла Delphi 2007.

Можно ли как-нибудь изменить код, чтобы он работал в обеих версиях Delphi, не прибегая к IFDEFS?

1 Ответ

2 голосов
/ 04 ноября 2011

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 не существует, и вам придется выяснить, каким должно быть состояние.

...