Преобразование 32-битного приложения в 64-битное приложение на C

StackOverflow https://stackoverflow.com/questions/411798

  •  03-07-2019
  •  | 
  •  

Вопрос

В настоящее время я работаю над преобразованием 32-битного приложения в 64-битное приложение на C. Это приложение в настоящее время работает на архитектуре x86 (Windows, osx, Unix, Linux). Поэтому, прежде чем приступить к написанию кода, я хотел знать, что мне нужно учитывать при конвертации приложения.

Это было полезно?

Решение

<Ол>
  • Узнайте, кто это написал. Они идиот? Они вы несколько лет назад? Вы можете задать им вопросы? Они знакомы с существованием нескольких платформ и систем? Знание мышления автора (ов) программы поможет вам понять проблемы, с которыми вы столкнетесь.
  • Настройте и запустите 64-битную машину / среду сборки.
  • Замените long на int. Помните, что LONG - это не long.
  • Замените (int)&x приведение типов и наберите intptr_t, а (unsigned int)&x - uintptr_t
  • Проверяйте все, что зависит от приведения структур к char* для выполнения арифметики с указателями.
  • Регулярный поиск \ < 4 \ > если вы предположили, что 4 = sizeof(void*)
  • Будьте терпеливы. Когда вы найдете проблему, посмотрите в другом месте, если такая же проблема существует, и оберните решение в макрос.
  • Старайтесь не использовать #ifdef RUN64 или что-либо подобное. Вы пожалеете об этом, если 128-битные платформы когда-либо войдут в моду.
  • Инкапсулируйте все ваши изменения с точки зрения некоторых централизованных макросов, которые скрывают различия в переносимости в других местах вашей программы.
  • Используйте тестер покрытия, чтобы убедиться, что вы покрыли все (при необходимости)
  • РЕДАКТИРОВАТЬ добавила <=> заметку, предложенную комментарием.

    Другие советы

    Одна потенциальная проблема, которая еще не упоминалась, заключается в том, что если ваше приложение читает или записывает двоичные данные с диска (например, читает массив структур с помощью fread), вам придется очень тщательно проверить и, возможно, получить два считыватели: один для устаревших файлов и один для 64-битных файлов. Или, если вы осторожно используете такие типы, как uint32_t и т. Д. Из заголовочного файла <stdint.h>, вы можете переопределить свои структуры, чтобы они были побитно-совместимыми. В любом случае, бинарный ввод / вывод стоит остерегаться.

    Это действительно зависит от приложения и от того, как оно было закодировано. Некоторый код можно просто перекомпилировать с помощью 64-разрядного компилятора, и он будет работать, но обычно это происходит только в том случае, если код был разработан с учетом переносимости.

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

    Практически каждое предупреждение о приведении и компиляции - это красный флаг, который необходимо проверить. Если код не был & Quot; предупреждение clean & Quot; для начала это также признак того, что может потребоваться много работы.

    Если вы использовали правильные типы для ваших значений - например. size_t, ptrdiff_t, uintptr_t, целочисленные типы int фиксированного размера из stdint.h, где это уместно - и не имеют жестких значений размеров, ваш код должен работать "из коробки".

    Основная проблема, с которой вы сталкиваетесь при переходе на 64-битную версию, состоит в том, что размер указателей различен (64-битная вместо 32-duh). Размер целых чисел и размер long также могут различаться в зависимости от платформы.

    Почему это проблема? Ну, это не так, если только ваш код не предполагает, что sizeof (int) == sizeof (void *). Это может привести к неприятным ошибкам указателя.

    Ну, в принципе, количество изменений довольно мало, но это все равно будет серьезной задачей, если приложение не будет тщательно написано, чтобы быть несколько портативным для начала.

    Основное отличие состоит в том, что указатели имеют ширину 64 бита, , но большинство других типов данных не изменяются. Int по-прежнему 32-битный, а long, вероятно, также 32-битный. Так что, если ваш код преобразуется между int и указателями, это сломается. Точно так же любая структура или аналог, который зависит от определенного смещения элемента, может сломаться, потому что другие элементы теперь могут быть больше, и поэтому изменить смещение.

    Конечно, ваш код никогда не должен полагаться на эти уловки, так что в идеальном мире это вообще не будет проблемой, и вы можете просто перекомпилировать, и все будет работать. Но вы, вероятно, не живете в идеальном мире ...;)

    Два основных различия между 32-битным и 64-битным программированием в C - это sizeof (void *) и sizeof (long). Основная проблема, с которой вы столкнетесь, заключается в том, что большинство систем Unix используют стандарт I32LP64, который определяет длину до 64 бит, а Win64 использует стандарт IL32LLP64, который определяет длину до 32 бит. Если вам требуется поддержка кроссплатформенной компиляции, вы можете использовать набор архитектурных определений типов для 32-разрядных и 64-разрядных целых чисел, чтобы гарантировать, что весь код будет работать согласованно. Это предоставляется как часть stdint.h как часть стандарта C99. Если вы не используете компилятор C99, вам может потребоваться развернуть собственный эквивалент

    Как уже отмечалось, основной проблемой для конвертации будет код, который принимает sizeof (int) == sizeof (long) == sizeof (void *), код для поддержки данных, записанных на диск, и код для межплатформенного IPC .

    Для хорошего обзора истории этого взгляните на эту статью из очереди ACM.

    Уже есть много хороших ответов.

    Рекомендуется использовать Gimpel Lint . Он может указать именно те типы конструкций, которые являются проблематичными. Если ваш опыт похож на мой, он также покажет вам множество ошибок в системе, не связанных с 32/64 битным портом.

    Все о 64-битных версиях для разработчиков:

    Статьи о 64-разрядной разработке

    Коллекция ссылок 64-разрядные ресурсы

    Инструмент Viva64

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top