#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. Поскольку, похоже, ни у кого другого нет предложений получше, я принимаю ваш ответ.