Как программист, что мне нужно беспокоиться при переходе на 64-битные окна? - PullRequest
31 голосов
/ 13 февраля 2009

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

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

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

РЕДАКТИРОВАТЬ: Вот хороший список 64-битных ошибок переноса.

Ответы [ 8 ]

22 голосов
/ 13 февраля 2009

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

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

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

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

Миграция кода .NET может быть проще, если у вас 100% «тип безопасного управляемого кода». Вы можете просто скопировать его на 64-битную платформу и успешно запустить под 64-битным CLR. Установите этот флажок MSDN при переносе 32-разрядного управляемого кода в 64-разрядный.

Кстати, hanselman написал о теме недавно.

3 голосов
/ 13 февраля 2009

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

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

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

2 голосов
/ 13 февраля 2009

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

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

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

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

0 голосов
/ 13 февраля 2009

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

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

0 голосов
/ 13 февраля 2009

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...