Как в delphi скомпилировать 64 битное приложение
Поскольку я верю, что 64bit Delphi-компилятор появится в ближайшее время, Мне интересно, кто-нибудь знает, какие программы , Которые сейчас 32bit будут компилироваться и работать без каких-либо изменений .__ когда используя компилятор 64bit.
И если существует общее правило, какие изменения мы должны Систематически вносить в наши старые программы для компиляцииAs 64bit?
Хорошо быть готовым, когда компилятор 64bit внезапно появится здесь .
Любое предложение будет высоко ценится.
Во-первых, отказ от ответственности: хотя я работаю на Embarcadero. Я не могу говорить за своего работодателя. То, что я собираюсь написать, основано на моем собственном мнении о том, как должен работать гипотетический 64-битный Delphi, но могут быть или не быть конкурирующие мнения и другие предвиденные или непредвиденные несовместимости и события, которые вызывают принятие альтернативных проектных решений.
Существует два целочисленных типа, NativeInt и NativeUInt, размер которых Будет колебаться между 32-разрядным и 64-разрядным в зависимости от платформы. Они были .__ вокруг довольно много релизов. Никакие другие целочисленные типы не изменят размер В зависимости от разрядности цели.
Убедитесь, что любое место, которое основано на приведении значения указателя к целому числу .__ или наоборот, использует NativeInt или NativeUInt для целочисленного типа TComponent.Tag должен быть NativeInt в более поздних версиях Delphi.
Я бы предложил не используйте NativeInt или NativeUInt для значений, не основанных на указателе . Старайтесь, чтобы ваш код был семантически одинаковым между 32-битным и 64-битным. Если вам нужно 32 бита диапазона, используйте Integer; если вам нужно 64 бита, используйте Int64. Таким образом, ваш код должен работать одинаково на обеих битах. Только если вы преобразуете в и из какого-либо значения Pointer, например, ссылку или THandle, вы должны использовать NativeInt.
Используйте PByte для арифметики указателей, где это возможно, вместо NativeInt или NativeUInt . Этого будет достаточно для большинства целей, и он более безопасен для типов, потому что его нельзя (легко) принять за обычный целочисленный тип, и наоборот.
Подобные указателю вещи должны следовать правилам, аналогичным указателям: ссылки на объект .__ (очевидно), но также такие вещи, как HWND, THandle и т.д.
Не полагайтесь на внутренние детали строк и динамических массивов, таких как Их данные заголовка.
Наша общая политика в отношении изменений API для 64-битных систем должна заключаться в том, чтобы поддерживать Тот же API между 32-битными и 64-битными, где это возможно, даже если это означает, что 64-битный API не обязательно использует преимущества машина. Для примера TList, вероятно, будет обрабатывать только элементы MaxInt div SizeOf (Pointer) , Чтобы сохранить число, индексы и т.д. Как целое число. Поскольку тип Integer не будет плавать (т. Е. Изменять размер в зависимости от разрядности), мы Не хотим, чтобы на клиентский код оказывалось волновое воздействие: любые индексы, которые Округлялись через целочисленный тип переменная, или индекс цикла for, будет усечена и потенциально может вызвать незначительные ошибки.
В тех случаях, когда API-интерфейсы расширены для 64-разрядных систем, они, скорее всего, будут выполняться с помощью Дополнительной функции/метода/свойства для доступа к дополнительным данным, и этот API также будет поддерживаться в 32-разрядных системах. Например, стандартная подпрограмма Length () , Вероятно, будет возвращать значения типа Integer для аргументов строки типа Или динамического массива; если кто-то хочет иметь дело с очень большими динамическими массивами , может также существовать подпрограмма LongLength (), чья реализация в 32-битной системе такая же, как Length (). Функция Length () выдала бы исключение В 64-битной среде, если применить его к динамическому массиву с более чем 2 ^ 32 Элементами.
В связи с этим, вероятно, будет улучшена проверка ошибок для операций сужения .__ в языке, особенно сужение 64-битных значений .__ до 32-битных положений. Это может привести к невозможности назначения возвращаемого значения длины Для местоположений типа Integer, если Length (), Вернул Int64. С другой стороны, специально для магии компилятора Функций, таких как Length (), может быть какое-то преимущество полученной магии, от .__ до, например. переключить тип возврата на основе контекста. Но преимущество не может быть Аналогичным образом используется в немагических API.
Динамические массивы, вероятно, будут поддерживать 64-битную индексацию. Обратите внимание, что массивы Java Ограничены 32-битной индексацией даже на 64-битных платформах.
Строки, вероятно, будут ограничены 32-битной индексацией. У нас есть трудное время Придумать реальные причины для людей, которым нужны строки размером 4 ГБ + Это действительно строки, а не просто управляемые блоки данных, для которых динамические массивы Могут также служить.
Возможно встроенный ассемблер, но с ограничениями, такими как неспособность свободно смешиваться с кодом Delphi; Есть также правила об исключениях и макете стекового фрейма, которые должны соблюдаться в x64.
Прежде всего, FreePascal уже предлагает 64-битную поддержку. Это не Delphi, хотя.
Во-вторых, я ожидаю примерно тех же проблем, которые существовали во время обновления Delphi 1 до Delphi 2. Самая большая проблема связана в основном с адресным пространством, и проблема здесь в том, что указатели будут расширены с 4 байтов до 8 байтов. В WIN16 они должны были составлять 2 байта, и был необходим трюк, чтобы преодолеть границу 64 КБ, используя сегменты и смещения для указателей. (С возможностью использования сегментов по умолчанию для нескольких задач.)
Также вероятно, что некоторые типы данных станут больше, чем сейчас. Целочисленный тип будет, скорее всего, 8 байтов. (Раньше в Windows 2 было всего 2 байта). Перечисления, вероятно, тоже станут больше. Но большинство других типов данных, скорее всего, сохранят свой текущий размер, поэтому изменений здесь не так уж много.
Другой проблемой будут требования к памяти. Поскольку указатели будут иметь длину 8 байт, приложение, которое использует их много, также будет потреблять намного больше памяти. Список с 10 000 указателей увеличится с 40 000 до 80 000 байтов. Возможно, вы захотите использовать немного больше памяти, чем в 32-битной системе.
Скорость также немного изменится. Поскольку процессор теперь обрабатывает 8 байтов одновременно, он может обрабатывать данные намного быстрее. Но поскольку указатели и некоторые типы данных становятся больше, получение или отправка их на какое-либо устройство или в память будет происходить немного медленнее. В общем, ваши приложения будут немного быстрее в целом, но некоторые части могут на самом деле стать медленнее!
Наконец, изменения в Windows API потребуют от вас использования 64-битных функций API. Возможно, компилятор Delphi сделает что-то умное, чтобы код вызывал 32-битные функции API, но это снизило бы производительность, потому что процессор теперь переключается между собственным 64-битным режимом и эмулированным 32-битным режимом.
Многие подобные вопросы были заданы, когда было объявлено, что Delphi 2009 будет создавать только приложения Unicode. В конце концов оказалось, что большая часть существующего кода работает без каких-либо изменений. Хитрые части были кодом, который предполагал, что SizeOf(Char) = 1 и сторонние компоненты могут это делать.
Вам следует использовать SizeOf(Pointer) вместо SizeOf(NativeInt) , если вы хотите, чтобы ваш код работал с Delphi 2007. В Delphi 2007 имеется неудачная ошибка, из-за которой SizeOf(NativeInt) возвращает 8 вместо 4, как и должно быть. Это было исправлено в Delphi 2009.
В зависимости от вашего кода, вы можете попробовать скомпилировать его, используя FreePascal, который поддерживает как 32-битную, так и 64-битную компиляцию. Компилятор предупредит вас о возможных ошибочных местах в вашем коде.
Пока Embarcadero не публикует официальную информацию об их 64-битной реализации, сказать нелегко. Вы должны проверять любое приведение к/от Pointer, Integer и Cardinal, предполагая, что они имеют собственный размер платформы, включая свойства объекта и ссылки (т.е. сохраняют Integer в свойстве TObject, являющемся указателем, или используя Tag для хранения ссылок, а не чисел). ).
Вы также должны убедиться, что ни один код не использует эффект «обтекания» при увеличении (или уменьшении) значения до его максимального (минимального) размера.
Проверяйте любой код в структурах, которые зависят от размера данных, и не правильно используете SizeOf (), и в целом этот SizeOf () всегда используется, когда размер данных имеет значение. Проверьте код, который записывает/считывает данные в файлы, если размеры могут измениться, особенно если необходимо обмениваться данными между 32- и 64-битным кодом.
Подавляющее большинство простых приложений должно работать просто отлично. Насколько я вижу, только приложения, которые вручную используют указатели, находятся в опасности. Действительно, если указатель теперь 64-битный, и вы используете его в вычислениях вместе с целыми числами или кардиналами (которые по-прежнему 32-битные по умолчанию), у вас возникнут проблемы. Я также думаю, что довольно распространено, что объявления для функций API, которые принимают указатели в качестве аргументов, используют cardinal s вместо (целого без знака) собственного целочисленного типа.
Чтобы сделать код, который хорошо работает на любой платформе, нужно использовать NativeUInt s (IIRC, сейчас у вас нет компилятора Deplhi) вместо cardinal s при работе с указателями и целыми числами одновременно.
Помимо очевидного указателя <-> int задач: (используя intptr/nativeint/ptrint и т.д.)
Проблема с упаковкой записей - это то, что я заметил при портировании существующих заголовков на win64.
Компиляция 64 - битных приложений возможна ли? Наверное нужно менять компилятор на 64 битный, как это осуществить? Нужно программы и Длл под 64 бит создавать.
И еще вопрос - Дельфи компилятор в современных версиях среды уже далеко ушел от 4-й используемой в Хиасме. Можно ли его обновить как-то, ведь там новые инструкции и оптимизации кода наверняка имеются.
Редактировалось 2 раз(а), последний 2019-02-05 12:07:47
Можно ли его обновить как-то, ведь там новые инструкции и оптимизации кода наверняка имеются.
Имеется 64 бита и Юникод. Можно подключить, но только к тому пакету, что я выше дал ссылку - там основная работа мной проведена, никто другой что-то подобное наверняка не возьмется делать. А с учетом легальности использования - FPC предпочтительнее.
Редактировалось 1 раз(а), последний 2019-02-05 12:32:06
Netspirit, спасибо!
--- Добавлено в 2019-02-05 12:59:59
А как переключаться между 32 и 64 битной компиляцией? Или под каждую битность свой компилятор нужно иметь? И нельзя ли официальный дельфийский компилятор прикрутить? Под ФПС многое не работает уже проверено практикой.
Редактировалось 2 раз(а), последний 2019-02-05 13:08:43
А как перекличаться между 32 и 64 битной компиляцией? Выбрать соответствующий компилятор в списке компиляторов (возле кн. "Компилировать")
Под ФПС многое не работает уже проверено практикой. Это была практика на старой версии. На новой - вырабатывай новую практику.
Спасибо Netspirit. Значит можно добиться полной совместимости? Удивлен что над этим кроме тебя никто не работает. Это же первоочередная задача легализации Хиасм контента.
Hiasm + Flowstone + CopperCube + Unity + UE = SuperCow Power
Netspirit, правильно я понимаю, что в этой реализации опять присутствует KOL?
Он оставлен для для совместимости старых компонентов и внутренних задач кодогенератора?
Могу-ли я в этой версии писать TStringList, TmemoryStream, а не КОЛовские FList : PStrList; FList = NewStrList; и P : PStream; P=NewMemoryStream; и так далее?
Я имею ввиду, возможность использования нормальных, человеческих библиотек delphi.
Или всё-же надо делать порты в KOL?
В предыдущей заметке я рассказывал о начале работ по адаптации наших приложений к платформе Win64. Эта заметка является продолжением.
Итак, обновив сторонние библиотеки и компоненты, а так же избавившись от устаревшего и неиспользуемого кода, настало время адаптировать наш код. В отличии от процесса перехода на юникод, проблемных пунктов оказалось совсем чуть-чуть, однако рутины, по исправлению - примерно столько же. Но по порядку.
Первое, на что стоит обратить внимание - это работа с указателями через Integer: в Win64 тип Pointer стал 64-битным (т.е. 8 байт), а тип Integer остался 32-битным (т.е. 4 байта). Подробно об этом писал Александр Алексеев: "Введение в 64 бита на Windows" (обязательно почитайте, если ещё не читали).
Суть проблемы в том, что в Win64 цепочка преобразований Pointer -> Integer -> Pointer (например, при сохранении ссылки на объект в свойство компонента Tag с приведением типа через Integer) приводит к искажению начального значения (верхние 4 байта срезаются, а ещё Integer - знаковое), соответственно можно получить AV, либо вылет в непредсказуемых местах. Проблема усугубляется тем, что проявится она только после того, как выделение памяти приложению перейдёт границу в 2 Гб, что при обычном использовании прикладных приложений - редкость, и воспроизвести такие ошибки будет очень трудно.
Поэтому, ещё до каких-либо исправлений в исходниках, я написал очень простой код:
И разместил его в секции иницализации самого первого модуля наших приложений (обернув отдельным дефайном - в релизе такой радости никому не нужно). Код выделяет X Гб памяти при старте приложения ещё до инициализации сторонних библиотек (я указал X = 6 -- чтобы наверняка :), и это позволяет воспроизводить ошибки без проблем.
Далее тупо поиск и пересмотр кода (замена Integer на NativeInt). Слова для поиска были такими:
Ну и конечно ассемблерный код (некоторые asm-процедуры могут скомпилироваться, но будут вылетать Win64).
Итого с тестами это заняло примерно 30 часов (т.е. примерно столько же, сколько на обновление сторонних библиотек). Сейчас все тесты проходят и основные свои функции приложения выполняют без ошибок (была пара случаев, когда проблемные места я проглядел - выделение большого куска памяти при старте выявило их довольно быстро). Осталось лишь настроить сервер сборки.
Делфи 64 бит на своем пути, как все знают (каждый программист Delphi, по крайней мере) . Помимо того, что codegear говорит о преимуществах 64-битного приложения Delphi (и codegear не говорит много о), что я выиграю от 64-битного приложения Delphi? Это действительно хорошая идея, чтобы портировать мое приложение до 64 бит, как только codegear выпускает его?
EDIT:
Я просто спрашиваю, потому что я хочу все мнения, которые я могу иметь. Сейчас я могу сказать, что действительно нужно больше памяти, доступной для моего приложения, потому что она потребляет много ресурсов. Я действительно мог бы использовать больше скорости, если это возможно. Мне не нужны расширения shell ни Плагины.
мои клиенты также спрашивают меня о версии x64 моего приложения, но я действительно не понимаю, почему они просят об этом, потому что они на самом деле юристы, которые понятия не имеют, что такое 64-битное приложение.
редактировать
Я на самом деле не участвуют непосредственно в разработку приложения. Я являюсь частью технологической команды, и я создаю вещи, которые другие разработчики в компании, в которой я работаю, используют для разработки окончательного приложения. Итак, моя работа-делать технические вещи, и перенос приложения на x64-это то, что я делаю, но мне нужно объяснить, почему я делаю это своему начальству.
64-разрядная программа имеет следующие преимущества перед той же, скомпилированной для 32-разрядной (x86):
дополнительные регистры. 64-разрядные чипы x86 имеют еще несколько регистров и это может теоретически (если компилятор использует преимущество) привести к более быстрому коду в некоторых случаях.
больше памяти. С 32-битной программой вы, как правило, были ограничены либо адресным пространством 2GB, либо адресным пространством 4GB в целом, если вы скомпилированы с /LARGEADDRESSAWARE , Что было около 3,5 ГБ на практике из-за разделения ядра/пространства пользователей Windows. 64-разрядный процесс может решить гораздо больше. Это важно только в том случае, если вашему приложению требуется много памяти.
возможность создания плагинов для 64-битных программ, как Explorer. Если вы не используете COM для плагина, где данные маршалируются, вы не можете смешивать 32-разрядный и 64-разрядный код в одном процессе в Windows, например 64-разрядный EXE, загружающий 32-разрядную DLL. Если вы хотел написать плагин Explorer, например, вы не могли бы работать с 64-разрядной версией Explorer со старыми версиями Delphi. Вы сможете с 64-разрядной версии.
Delphi-specific:компилятор будет использовать SSE / SSE2 - инструкции для вычислений с плавающей запятой, где текущий 32-битный компилятор использует только инструкции x87 FPU(я думаю .) Это должно дать увеличение скорости для математики с плавающей запятой. Вы, наверное, даже не заметит, если ваше приложение не сильно зависит от FP (игра, возможно, или приложение для обработки данных, такого рода вещи.)
ответ на ваш вопрос "будет ли мне полезно иметь 64-битное приложение Delphi?"это сильно зависит от конкретного приложения. в общем, вряд ли будет много пользы, кроме, возможно, небольшого увеличения скорости. Не полагайтесь на 64-бит, чтобы ускорить медленное приложение: вам все равно нужно будет сделать алгоритмические изменения большой скорости. 64-бит-это не волшебная пуля. Кроме того, вам нужно только изменить, если вы уже столкнулись с одним из ограничений, наложенных 32-битным - я подозреваю, что вы этого не сделали, иначе вы не задавали бы вопрос.
Если вы решите конвертировать, вы можете найти этой теме очень полезно.
но еще одна вещь: даже если вам не нужно меняться, вы можете захотеть, особенно если ваше приложение является личным проектом. Вы можете изучите материал, ваш код будет более качественным, когда вы исправите 32/64-битные проблемы, и такой проект может быть забавным. Вы же программист, в конце концов :)
Edit: Я вижу вы обновили свой вопрос с " я могу сказать, что мне действительно нужно больше памяти, доступной для моего приложения, потому что оно потребляет много ресурсов. Я действительно мог бы использовать больше скорости, если это возможно."
какие ресурсы? Память? 64-бит даст вам больше адресное пространство, вот и все. Он не даст вам больше дескрипторов GDI и т. д., Если они считаются ресурсами. Однако, если вам действительно нужно больше памяти, то 64-битная будет стоить преобразования.
"больше скорости", если вы хотите большой разница, скорее всего, будет достигнута через алгоритмические или потоковые изменения, чем через 64-битный компилятор.
" мои клиенты также спрашивают меня о версии x64 моего приложения, но я действительно не понимаю, почему они просят об этом, потому что они на самом деле юристы, которые понятия не имеют, что такое 64-битное приложение." скорее всего, они слышали, что 64-бит лучше или быстрее. В идеальном мире у клиентов были бы реальные требования, но это не всегда так. Прагматически говоря, если клиент хочет чего-то подобного, может быть, стоит конвертировать просто потому, что это делает их счастливыми: счастливые клиенты хороши, и они могут заплатить вам за новая версия, и это может помочь репутации вашей компании из уст в уста.
У вас есть фактическая потребность в доступе к большой (>4 ГБ) памяти в вашем приложении, как обработка видео или изображений, или обработка огромных объемов данных очень быстро? Является ли ваше приложение расширением оболочки, которое должно работать на 64-разрядных версиях Windows? У вас есть клиенты или клиенты, которые жалуются, потому что 64-разрядная версия вашего приложения недоступна?
Если бы у вас была потребность в немедленном обновлении вашего приложения до 64-битного, вы бы уже знали об этом. Раз ты этого не делаешь, ты . вероятно, у вас есть много времени для этого - помните, что 32-разрядные версии большинства приложений отлично работают на 64-разрядных версиях Windows.
Если вы пишете расширения оболочки, вы уже знаете, почему вам нужно 64. В моем случае у меня есть DLL, которая загружается проводником Windows, и она не может, абсолютно не будет загружать 32-разрядную DLL. Есть приложения, которые выиграют от 64-бит, но большинство, IMO не будет. И для таких вещей, как моя, 64-бит больше раздражает, чем что-либо еще.
хорошая идея? Только если вы думаете, что это сделает вас больше $$$. В противном случае время лучше потратить на улучшение качества или добавление функций. Если вы используете чистые собственные элементы управления и библиотеки VCL, вам, вероятно, придется ждать сторонней поддержки, чтобы догнать. Я все еще исправляю и заменяю библиотеки, связанные с преобразованием в Unicode.
большинству программ все равно.
У меня есть ровно одна программа, которую я написал, что я бы сделал 64-битную версию, и это было бы увеличить размер кэша, и даже тогда это только потому, что то, что я думаю, было бы лучшим компромиссом, ставит максимальное использование памяти несколько более 2 ГБ.
одна ситуация, когда 64 бит будет иметь значение для данных параллельных, многопоточных численных приложений на многоядерных машинах. Для такого приложения 32-битное адресное пространство может быть ограничено, если данные не могут быть разделены на достаточно мелкие части.
кроме этого, самый большой толчок к 64 бит для расширений для других программ. Например, расширения оболочки, надстройки Excel, расширения MATLAB и т. д.
нет, держите приложение 32 бит.
"мои клиенты также спрашивают меня о версии x64 моего приложения, но я действительно не понимаю, почему они просят об этом"
ваши пользователи хотят, чтобы ваше приложение отлично работало на 64-битной версии Windows. Вы должны проверить это и сказать им, что вы протестировали его и что он работает правильно на 64 бит Windows.
У меня такая проблема с некоторыми из моих клиентов. Это в основном происходит потому, что ИТ-отделы в своих соответствующих компаниях имеют контрольный список вещей, которые необходимо "учитывать", когда компания покупает новое программное обеспечение (или утверждает обновления и т. д.). Время от времени эти контрольные списки обновляются, чтобы лучше отражать современный ИТ-ландшафт, но это не всегда означает, что новые элементы имеют смысл в контексте вашего собственного прикладного программного обеспечения.
в какой-то момент, люди начал говорить: "поскольку у нас есть 64bit Windows XP/Vista / 7 и т. д., Нам нужно убедиться, что любое новое программное обеспечение тоже 64bit". Как разработчики, мы знаем, что это не обязательно так, но если вы пытаетесь объяснить это нетехническим людям, это обычно происходит, когда вы пытаетесь скрыть тот факт, что ваше приложение на самом деле не 64bit. Когда вы маленький поставщик на заказ в конкуренции с другими поставщиками, вы не можете позволить своей работе потерять из-за в значительной степени неуместной/неважной "функции" на чьем-то контрольный список.
мой подход до сих пор состоял в том, чтобы сообщить клиентам, что программное обеспечение было тщательно протестировано и проверено на 64-битных окнах, но разработано так, чтобы одна и та же точная версия могла работать на 32-битных или 64-битных окнах. Это совершенно верно, потому что мои приложения в основном основаны на Delphi 2007, и в прошлом году или около того я начал делать все свое тестирование на 64bit Win7 в качестве первого средства (а затем снова выполнять подмножество тестов под 32bit XP, на ключевых вехах).
в стороне, как в среде малого бизнеса, так и (что более удивительно) дома, я видел гораздо больше 64bit Win7 устанавливает, чем 32bit. Большинство новых машин, которые я видел за последние 6 месяцев, похоже, пришли с 64bit Win7, что я нахожу довольно интересным.
Мне также нравится комментарий The_Fox к исходному вопросу - возможно, мне придется соответствующим образом обновить заставки. Особенно, если я могу обнаружить, что программа работает на 64-битной версии Окна.
Читайте также: