THandleStream.Создание с помощью INVALID_HANDLE_VALUE не компилируется

#delphi #delphi-2007 #delphi-xe2

#delphi #delphi-2007 #delphi-xe2

Вопрос:

Следующий код, используемый для компиляции с Delphi 2007:

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

В Delphi XE он завершается с ошибкой
E1012: постоянное выражение нарушает границы поддиапазона.

Причина заключается в объявлении THandleStream.Создать:

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. @David, это больше ответ, чем комментарий 😉

2. @TLama Посмотрев на объявление THandleStream. Создавайте в старых версиях Delphi, теперь я понимаю проблему.

Ответ №1:

THandleStream.Create объявляет свой параметр дескриптора как имеющий тип Integer (signed). 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 не существует, и вам придется решить, каким это условие действительно должно быть.

Комментарии:

1. Спасибо, Дэвид. Я боялся, что мне придется использовать cond. Сборник. Я использую jedi.inc во всех своих подразделениях, так что это просто вопрос проверки {$IFDEF DELPHIXE2_UP}.

2. @David, ты можешь использовать $IFDEF VER230 или лучше $IF CompilerVersion >= 23

3. @tlama да, я знаю об этом, но я также знаю, что у всех разные предпочтения для этого

4. Это скорее RTLVersion >= 23 , чем CompilerVersion

5. Поскольку, похоже, ни у кого другого нет предложений получше, я принимаю ваш ответ.