В 64-битной версии не ожидается поддержка 64-битной версии, которая больше не может ждать возможности перенести нашу существующую базу кода в unicode и 64-bit за один раз. Однако было бы неплохо, если бы мы уже подготовили наш код для 64-бит при выполнении перевода в Юникод. Это позволит свести к минимуму воздействие в случае, если оно наконец появится в версии 2020. Любые предложения, как подойти к этому, не внося много шума, если он не появится до 2020 года?
Как подготовиться к 64-битам при переходе на Delphi 2010 и Unicode
Ответ 1
Там другой подобный вопрос, но я также повторю свой ответ здесь, чтобы убедиться, что многие люди видят эту информацию:
Прежде всего, отказ от ответственности: хотя я работаю на Embarcadero. Я не могу говорить за своего работодателя. То, что я собираюсь написать, основано на моем собственном мнении о том, как должна работать гипотетическая 64-разрядная Delphi, но могут быть или не быть конкурирующие мнения и другие предусмотренные или непредвиденные несовместимости и события, которые вызывают альтернативные дизайнерские решения.
Это сказало:
-
Существует два целочисленных типа: NativeInt и NativeUInt, размер которых будет плавать между 32-битными и 64-битными в зависимости от платформы. Они были вокруг довольно много выпусков. Никакие другие целочисленные типы не изменят размер в зависимости от битности цели.
-
Убедитесь, что в любом месте, которое полагается на значение указателя, integer или наоборот использует NativeInt или NativeUInt для целого числа тип. TComponent.Tag должен быть NativeInt в более поздних версиях Delphi.
-
Я бы предложил не использовать NativeInt или NativeUInt для значений, не содержащих указателей. Постарайтесь, чтобы ваш код семантически совпал между 32-битным и 64-битным. Если вам нужно 32 бита диапазона, используйте Integer; если вам нужны 64 бита, используйте Int64. Таким образом, ваш код должен работать одинаково на обеих битах. Только если вы используете значение типа указателя какого-либо типа, например ссылку или THandle, следует использовать NativeInt.
-
Пойнтер-подобные вещи должны следовать аналогичным правилам указателям: объект (очевидно), но также такие вещи, как HWND, THandle и т.д.
-
Не полагайтесь на внутренние детали строк и динамических массивов, например их данные заголовка.
-
Наша общая политика по изменениям API для 64-разрядной версии должна состоять в том, чтобы сохранить один и тот же API между 32-битными и 64-битными, если это возможно, даже если это означает, что 64-битный API не обязательно использует машину. Для Например, TList, вероятно, будет обрабатывать MaxInt div SizeOf (Pointer) элементов, чтобы сохранить Count, индексы и т.д. как Integer. Поскольку Тип Integer не будет плавать (т.е. Изменить размер в зависимости от битности), мы не хотят иметь волновой эффект на код клиента: любые индексы, которые round-tripped через переменную типа Integer или индекс for-loop, будет усекаться и потенциально вызвать тонкие ошибки.
-
Если API-интерфейсы расширены для 64-разрядных, они, скорее всего, будут выполнены с помощью дополнительную функцию/метод/свойство для доступа к дополнительным данным, и это API также будет поддерживаться в 32-разрядной версии. Например, стандарт Length() процедура, вероятно, вернет значения типа Integer для аргументов тип строки или динамический массив; если кто-то хочет иметь дело с очень большими динамических массивов, может быть и процедура LongLength(), чья реализация в 32-бит такая же, как Length(). Длина() будет бросать исключение в 64-битном, если применяется к динамическому массиву с более чем 232 элементы.
-
В связи с этим, вероятно, будет улучшена проверка ошибок для сужение операций на языке, особенно сужение 64-битных значений до 32-разрядных местоположений. Это повлияло бы на удобство назначения возвращаемое значение Length для местоположений типа Integer, если Length(), вернулся Int64. С другой стороны, специально для компилятора-магии функции, такие как Length(), может быть какое-то преимущество магии, например, переключите тип возврата на основе контекста. Но преимущество не может быть аналогично взяты в не магических API.
-
Динамические массивы, вероятно, поддерживают 64-битную индексацию. Обратите внимание, что Java массивы ограничены 32-разрядной индексацией даже на 64-битных платформах.
-
Строки, вероятно, будут ограничены 32-разрядной индексацией. У нас есть время придумывает реалистичные причины для людей, желающих 4GB + строки это действительно строки, а не только управляемые капли данных, для которых динамические массивы могут также служить.
-
Возможно, встроенный ассемблер, но с ограничениями, например, неспособный свободно смешивать с кодом Delphi; существуют также правила вокруг исключений и макета фрейма стека, которые должны соблюдаться на x64.
Ответ 2
Сначала просмотрите места, где вы взаимодействуете с не-delphi-библиотеками и api-вызовами, они могут отличаться. В Win32 библиотеки со стандартным вызовом stdcall называются _SomeFunction @4 (@4, указывающие размер параметров и т.д.). На Win64 существует только одно соглашение о вызове, а функции в dll больше не оформлены. Если вы импортируете функции из DLL файлов, вам может потребоваться их настройка.
Имейте в виду, что в 64-разрядной версии EXE вы не можете загрузить 32-разрядную DLL, поэтому, если вы зависите от сторонних DLL файлов, вы должны проверить и 64-разрядную версию этих файлов.
Кроме того, посмотрите на Integers, если вы зависите от их максимального значения, например, когда вы позволяете им переполняться и ждать момента, когда это происходит, это вызовет проблему, если размер целого будет изменен.
Кроме того, при работе с потоками и вы хотите сериализовать разные данные, включая целое число, это вызовет проблему, так как размер целого изменился, и ваш поток будет не синхронизирован.
Итак, в местах, где вы зависите от размера целого или указателя, вам нужно будет внести коррективы. При сериализации данных sush вам также нужно иметь в виду эту проблему размера, поскольку это может привести к несовместимости данных между 32 и 64-битными версиями.
Кроме того, компилятор FreePascal с IDE Lazarus уже поддерживает 64-разрядную версию. Этот альтернативный компилятор Object Pascal не на 100% совместим с диалектом Borland/Codegear/Embarcadero Pascal, поэтому просто перекомпилировать его для 64-разрядного может быть не так просто, но это может помочь указать проблемы с 64-разрядными.
Ответ 3
Преобразование в 64 бит не должно быть очень болезненным. Начните с преднамеренного размера целого числа, где это имеет значение. Не используйте "integer" вместо Int32 для целых чисел размером 32 бита, а Int64 для целых чисел размером 64 бит. В последнем преобразовании бит определение Integer перешло от Int16 к Int32, поэтому вы играете в нем безопасно, указав точную глубину бит.
Если у вас есть встроенная сборка, создайте эквивалент pascal и создайте некоторые модульные тесты, чтобы гарантировать, что они работают одинаково. Выполните некоторые временные тесты и убедитесь, что сборка все еще работает достаточно быстро, чтобы сохранить. Если да, то вы захотите внести изменения в оба, как они нужны.
Ответ 4
Используйте NativeInt для целых чисел, которые могут содержать литые указатели.