Инструменты
В этом разделе описываются средства, доступные для подготовки 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.