Подтвердить что ты не робот

Как программист, что мне нужно беспокоиться при переходе на 64-битные окна?

Большая часть моего недавнего программирования была в 32-битной Windows с использованием C/С++/С#/VB6. В последнее время мои клиенты спрашивают, будет ли мой код работать в 64-битной Windows.

Мне интересно, какие устаревшие функции я могу использовать, которые будут разбиваться на 64-битную Windows? Каковы некоторые реальные проблемы, о которых мне нужно думать и беспокоиться?

Очевидно, что я буду тестировать свой код на 64-битной ОС, но я хотел бы знать, какие общие проблемы нужно искать. Я больше беспокоюсь о существующих двоичных файлах, но я открыт для комментариев о том, о чем беспокоиться при перекомпиляции (где это возможно).

EDIT: хороший список 64-битных ошибок портирования.

4b9b3361

Ответ 1

Статьи:

20 вопросов портирования кода С++ на 64-битной платформе

Забытые проблемы разработки 64-битных программ

64 бит, Wp64, Visual Studio 2008, Viva64 и все остальное...

Обнаружение ловушек во время миграции кода C и С++ в 64-разрядную Windows

архитектура AMD64 (EM64T)

и

Инструмент Viva64 - для проверки 64-разрядных программ:

Viva64: что это такое и для кого оно предназначено?

Ответ 2

Насколько мне известно, самая важная вещь о переносе кода C/С++ в 64-разрядную Windows - это проверить ваше приложение с включенными MEM_TOP_DOWN распределениями (AllocationPreference значение реестра), как описано в 4-гигабайтная настройка:

Чтобы принудительно распределять ассигнования из более высоких адресов перед более низкими адресами для целей тестирования, укажите MEM_TOP_DOWN при вызове VirtualAlloc или установите следующее значение реестра в 0x100000:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

Когда это имеет значение?

  • Если у вас есть существующие 32-разрядные EXE файлы, которые были построены с помощью /LARGEADDRESSAWARE опции компоновщика MSVC (или которые имеют флаг IMAGE_FILE_LARGE_ADDRESS_AWARE устанавливаются в их PE-заголовках с помощью других средств, таких как editbin.exe), затем они получают полное 4 ГБ виртуального адресного пространства в 64-битной Windows, и вы должны протестировать их с установленным значением реестра AllocationPreference.
  • Если у вас есть 32-разрядные DLL файлы, которые могут быть загружены EXE с большими адресами, вы должны протестировать их с установленным значением реестра AllocationPreference.
  • Если вы перекомпилируете свой код C/С++ в 64-разрядный EXE или DLL, вы должны протестировать его с установленным значением реестра AllocationPreference.

Если ваше приложение C/С++ попадает в одну из этих трех категорий и вы не тестируете с помощью распределений MEM_TOP_DOWN, тестирование вряд ли поймает любые ошибки усечения/подписи указателя в вашем коде.

Вторая важная вещь, если вы используете MSVC и перекомпилируете код C/С++ для 64-разрядной версии, - это использовать параметр компилятора /Wp64 для вашей 64-битной сборки:

  • Это заставит компилятор выдавать предупреждения для типов, которые усекают указатели или расширяют более мелкие интегральные типы в указатели (даже если используется reinterpret_cast или приведение в стиле C), а также некоторые другие проблемы с 64-разрядным переносом.
  • Да, документация говорит, что вместо компиляции с /Wp64 вы должны использовать компилятор, ориентированный на 64-битную платформу, но один не будет улавливать усечение/расширение указателя во время компиляции. Использование компилятора, который нацелен на 64-разрядный и, включающий параметр компилятора /Wp64 для 64-битной сборки, будет захватывать многие проблемы усечения/расширения указателя во время компиляции, и это сэкономит ваше время в длинных работать.
  • К сожалению, с MSVC 2008 это также приведет к "предупреждению командной строки" для каждой единицы перевода, в которой говорится, что параметр /Wp64 устарел. Я могу понять, почему опция устарела для 32-битных сборников (где это злой хак, который требует аннотации многих ваших typedef), но он досадно, что он также устарел для 64-битных сборников (где это действительно полезно).

Ответ 3

Возможно, было бы легче перенести .NET-код, если у вас есть 100% -ный "безопасный управляемый код типа". Вы можете просто скопировать его на 64-битную платформу и успешно запустить ее под 64-разрядной CLR. Проверьте ссылку MSDN на перенос 32-разрядного управляемого кода на 64-разрядный.

Btw, hanselman в блоге о теме недавно.

Ответ 4

Если вы говорите о 32-битных программах, вам нечего беспокоиться, так как Windows 64 будет запускать их под эмуляцию как 32-разрядные. Любые проблемы с будущими версиями Windows (например, Windows 7) скорее всего будут несовместимыми, чем проблемами с 64-разрядной ОС.

Однако, если ваш управляемый код скомпилирован для целевой платформы "Любой процессор" и вы делаете вызовы в неуправляемый код (например, PInvoke) или зависят от других сборок, тогда есть некоторые вещи, о которых нужно знать. Скотт Гензельман post о CLR x86/x64 охватывает это и является хорошим объяснением CLR на Win32/64.

При разработке 64-битных исходных программ Руководство по программированию для 64-разрядной Windows является хорошим руководством. В основном это сводится к указателям и размерам типов данных:)

Ответ 5

32-разрядные программы будут отлично работать на 64-битных окнах. До тех пор, как вы, конечно, не делаете никаких драйверов устройств.

Если вы впервые скомпилируете свое программное обеспечение в виде 64-битного программного обеспечения, вам необходимо позаботиться о следующем:

  • указатель имеет ширину 64 бит, а int - 32 бит. Не храните указатели в ints, ваш код сломается.
  • Для 64-битного процесса нужны 64-разрядные библиотеки DLL. Если вы зависите от DLL третьей части, убедитесь, что они также предоставляются в 64 бит. Если вам необходимо установить связь между 32-битным процессом и 64-разрядным процессом, вам понадобятся некоторые из многих способов IPC в Windows. Вызов функций напрямую невозможен.
  • Системные каталоги на 64-битных Windows отличаются от 32-разрядных версий Windows. Если у вас есть жесткие кодированные пути, вам может потребоваться проверить их снова.

Ответ 6

Если вы используете DLL-инъекцию по какой-либо причине, у вас возникнут проблемы.

Ответ 7

С точки зрения C/С++....

Очевидным является то, что размер int станет 8 байтами вместо 4 байтов. Если какой-либо из ваших кодов зависит от этого, вы можете получить неожиданные результаты. Структура и выравнивание переменных могут меняться. Вы можете преодолеть это с помощью пакета #pragma, но я не очень хорошо разбираюсь в настройках и упаковке.

Если вы используете какие-либо объединения с ints в них, поведение может измениться.

Если вы используете какие-либо структуры битовых полей, на основе ints дополнительные 32 бита могут вызвать путаницу. Значок бит не будет таким, как вы думали.

Если вы кодируете любые шестнадцатеричные константы и ожидаете, что знаки будут отрицательными, могут возникнуть проблемы. пример 0x8000000 - отрицательное число в виде журнала или 32-битное целое число. 0x80000000 как целое число на 64-битной платформе - это положительное число. для прямого набора знакового бита вам нужно будет использовать 0x80000000 00000000 (только встроенное пространство для чтения)

Также я ожидаю, что размер__t будет расти соответствующим образом. Если вы делаете какие-либо выделения на основе MAX_INT, они будут намного больше.

Чтобы избежать аномалий такого типа, я обычно придерживаюсь longs вместо ints.

Ответ 8

Является ли 32-разрядная эмуляция действительно доказательством пули? Я видел, что реестр выложен немного по-другому. Мне просто интересно, какие типичные вещи не работают...

Кроме того, каталог C:\windows\SYSTEM32 может содержать только 64-разрядные библиотеки DLL. Если у вас 32-разрядная DLL, вам нужно поместить ее в папку C:\windows\syswow64\