Новые типы данных
Существует три класса новых типов данных: целочисленные типы с фиксированной точностью, целочисленные типы точности указателя и типы указателей с определенной точностью. Эти типы были добавлены в среду Windows (в частности, в Basetsd.h), чтобы разработчики могли подготовиться к 64-разрядной версии Windows задолго до ее появления. Эти новые типы были производными от базовых целочисленных и длинных типов языка C, поэтому они работают в существующем коде. Поэтому используйте эти типы данных в коде сейчас, протестируйте код в 32-разрядной версии Windows и используйте 64-разрядный компилятор, чтобы заранее находить и устранять проблемы с переносимостью, чтобы драйвер был готов, когда 64-разрядная версия Windows станет доступной для тестирования.
Кроме того, внедрение этих новых типов данных сделает код более надежным. Чтобы использовать эти типы данных, необходимо проверить код на наличие потенциально небезопасного использования указателей, полиморфизма и определений данных. Чтобы обеспечить безопасность, используйте новые типы. Например, если переменная имеет тип ULONG_PTR, ясно, что она будет использоваться для приведения указателей для арифметических операций или полиморфизма. Невозможно указать такое использование напрямую с помощью собственных типов данных Win32. Это можно сделать с помощью производного именования типов или венгерской нотации, но оба метода подвержены ошибкам.
Fixed-Precision целочисленные типы
Типы данных с фиксированной точностью имеют одинаковую длину для 32-разрядного и 64-разрядного программирования. Чтобы запомнить это, их точность является частью имени типа данных. Ниже приведены типы данных с фиксированной точностью.
Тип | Определение |
---|---|
DWORD32 |
32-битное целое число без знака |
DWORD64 |
64-битное целое число без знака |
INT32 |
32-битное целое число со знаком |
INT64 |
64-битное целое число со знаком |
LONG32 |
32-битное целое число со знаком |
LONG64 |
64-битное целое число со знаком |
UINT32 |
Неподписанный INT32 |
UINT64 |
Неподписанный INT64 |
ULONG32 |
Unsigned LONG32 |
ULONG64 |
Unsigned LONG64 |
Pointer-Precision целочисленные типы
По мере изменения точности указателя (т. е. при компиляции для 32-разрядных платформ она становится 32 бита, а для 64-разрядных платформ — 64 бита), эти типы данных соответствующим образом отражают точность. Таким образом, при выполнении арифметики указателя можно с уверенностью привести указатель к одному из этих типов; Если точность указателя составляет 64 бита, тип равен 64 бита. Типы счетчиков также отражают максимальный размер, на который может ссылаться указатель. Ниже приведены типы точности указателя и счетчика.
Тип | Определение |
---|---|
DWORD_PTR |
Тип long без знака для точности указателя. |
HALF_PTR |
Целочисленный тип со знаком для точности полу pointer (16 бит в 32-разрядных системах, 32 бита в 64-разрядных системах). |
INT_PTR |
Целочисленный тип со знаком для точности указателя. |
LONG_PTR |
Тип long со знаком для точности указателя. |
SIZE_T |
Максимальное число байтов, на которое может ссылаться указатель. Используйте этот тип для счетчика, которое должно охватывать весь диапазон указателя. |
SSIZE_T |
Подписанный SIZE_T. |
UHALF_PTR |
неподписанный HALF_PTR. |
UINT_PTR |
неподписанный INT_PTR. |
ULONG_PTR |
Неподписанный LONG_PTR. |
Типы указателей Fixed-Precision
Существуют также новые типы указателей, которые явно определяют размер указателя. Будьте осторожны при использовании этих типов указателей в 64-разрядном коде. Если вы объявляете указатель с помощью 32-разрядного типа, система создает указатель путем усечения 64-разрядного указателя.
Тип | Определение |
---|---|
POINTER_32 |
32-разрядный указатель. В 32-разрядной системе это собственный указатель. В 64-разрядной системе это усеченный 64-разрядный указатель. |
POINTER_64 |
64-разрядный указатель. В 64-разрядной системе это собственный указатель. В 32-разрядной системе это 32-разрядный указатель со знаком. Обратите внимание, что небезопасно предполагать состояние бита верхнего указателя. |
Вспомогательные функции
Следующие встроенные функции (определенные в Basetsd.h) помогают безопасно преобразовывать значения из одного типа в другой:
unsigned long HandleToUlong( const void *h )
long HandleToLong( const void *h )
void * LongToHandle( const long h )
unsigned long PtrToUlong( const void *p )
unsigned int PtrToUint( const void *p )
unsigned short PtrToUshort( const void *p )
long PtrToLong( const void *p )
int PtrToInt( const void *p )
short PtrToShort( const void *p )
void * IntToPtr( const int i )
void * UIntToPtr( const unsigned int ui )
void * LongToPtr( const long l )
void * ULongToPtr( const unsigned long ul )
ПредупреждениеIntToPtr расширяет значение int , UIntToPtr — нулевое значение int без знака, знак LongToPtr — длинное значение, а ULongToPtr — нулевое значение типа long .