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


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

Существует три класса новых типов данных: целочисленные типы с фиксированной точностью, целочисленные типы точности указателя и типы указателей с определенной точностью. Эти типы были добавлены в среду 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 .