Поделиться через


Инструменты

В этом разделе описываются средства, доступные для подготовки 64-разрядного приложения. Windows 10 доступно для процессоров x64 и ARM64.

Включение файлов

Элементы API практически идентичны в 32- и 64-разрядной версиях Windows. Файлы заголовков Windows были изменены, чтобы их можно было использовать как для 32-, так и для 64-разрядного кода. Новые 64-разрядные типы и макросы определяются в новом файле заголовка Basetsd.h, который входит в набор файлов заголовков, включенных в Windows.h. Basetsd.h включает новые определения типов данных, помогающие сделать исходный код независимым от размера слова.

Новые типы данных

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

Предустановленный макрос

Компилятор определяет следующие макросы для идентификации платформы.

Макрос Значение
_WIN64 64-разрядная платформа. Сюда входят как x64, так и ARM64.
_WIN32 32-разрядная платформа. Это значение также определяется 64-разрядным компилятором для обеспечения обратной совместимости.
_WIN16 16-разрядная платформа

Следующие макросы относятся к архитектуре.

Макрос Значение
_M_IA64 Платформа Intel Itanium
_M_IX86 Платформа x86
_M_X64 Платформа x64
_M_ARM64 Платформа ARM64

Не используйте эти макросы, кроме как с кодом, зависящим от архитектуры. Вместо этого по возможности используйте _WIN64, _WIN32 и _WIN16.

Вспомогательные функции

Следующие встроенные функции (определенные в Basetsd.h) помогают безопасно преобразовывать значения из одного типа в другой.

void            * Handle64ToHandle( const void * POINTER_64 h ) 
void * POINTER_64 HandleToHandle64( const void *h )
long              HandleToLong(     const void *h )
unsigned long     HandleToUlong(    const void *h )
void            * IntToPtr(         const int i )
void            * LongToHandle(     const long h )
void            * LongToPtr(        const long l )
void            * Ptr64ToPtr(       const void * POINTER_64 p )
int               PtrToInt(         const void *p )
long              PtrToLong(        const void *p )
void * POINTER_64 PtrToPtr64(       const void *p )
short             PtrToShort(       const void *p )
unsigned int      PtrToUint(        const void *p )
unsigned long     PtrToUlong(       const void *p )
unsigned short    PtrToUshort(      const void *p )
void            * UIntToPtr(        const unsigned int ui )
void            * ULongToPtr(       const unsigned long ul )

Предупреждение

IntToPtr sign-extends the int value, UIntToPtr zero-extends the unsigned int value, LongToPtr sign-extends the long value, and ULongToPtr zero-extends the unsigned long value.

64-разрядный компилятор

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

При первом запуске компилятора, вероятно, будет создано много предупреждений об усечении указателя или несоответствии типов, например:

warning C4311: 'type cast' : pointer truncation from 'unsigned char *' to 'unsigned long '

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

Параметры и предупреждения 64-разрядного компилятора

Обратите внимание, что этот компилятор включает модель данных LLP64.

Существует вариант предупреждения, чтобы помочь в переносе в ТОО64. Параметр -Wp64 -W3 включает следующие предупреждения:

  • C4305: предупреждение об усечении. Например, "return": усечение с "unsigned int64" на "long".
  • C4311: предупреждение об усечении. Например, "приведение типа": усечение указателя с "int*_ptr64" на "int".
  • C4312: преобразование в предупреждение большего размера. Например, "приведение типа": преобразование из "int" в "int*_ptr64" большего размера.
  • C4318: передача нулевой длины. Например, передав константу ноль в качестве длины в функцию memset .
  • C4319: оператор Not. Например, "~": нулевое расширение "unsigned long" до "unsigned _int64" большего размера.
  • C4313: вызов семейства функций printf с конфликтующими описателями и аргументами типа преобразования. Например, "printf": "%p" в строке формата конфликтует с аргументом 2 типа "_int64". Другим примером является вызов printf("%x", pointer_value); это приводит к усечению верхних 32 битов. Правильный вызов — printf("%p", pointer_value).
  • C4244: то же, что и существующее предупреждение C4242. Например, "return": преобразование из "_int64" в "unsigned int", возможна потеря данных.

64-разрядный компоновщик и библиотеки

Для создания приложений используйте компоновщик и библиотеки, предоставляемые windows SDK. Большинство 32-разрядных библиотек имеют соответствующую 64-разрядную версию, но некоторые устаревшие библиотеки доступны только в 32-разрядных версиях. Код, вызывающий эти библиотеки, не будет связываться при сборке приложения для 64-разрядной версии Windows.