Подтвердить что ты не робот

Почему стандартные типы данных не используются в Win32 API?

Я изучаю программирование Visual С++ Win32 некоторое время. Почему существуют такие типы данных, как DWORD, WCHAR, UINT и т.д. Вместо, скажем, unsigned long, char, unsigned int и т.д.?

Я должен помнить, когда использовать WCHAR вместо const char *, и это действительно раздражает меня. Почему не используются стандартные типы данных? Будет ли это помогать, если я буду запоминать эквиваленты Win32 и использовать их для моих собственных переменных?

4b9b3361

Ответ 1

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

И причина, по которой эти типы определены так, как они есть, вместо использования int, char и т.д., заключается в том, что он удаляет "то, что компилятор считает, что int должен быть определен как" из интерфейс ОС. Это очень хорошо, потому что, если вы используете компилятор A или компилятор B или компилятор C, все они будут использовать одни и те же типы - только заголовок файла интерфейса библиотеки должен делать правильную вещь, определяющую типы.

Определяя типы, которые не являются стандартными, легко изменить int с 16 до 32 бит, например. Первые компиляторы C/С++ для Windows использовали 16-битные целые числа. Только в середине-конце 1990 года Windows получила 32-битный API, и до этого момента вы использовали int, который был 16-бит. Представьте, что у вас есть хорошо работающая программа, в которой используется несколько сотен переменных int, и внезапно вам нужно изменить ВСЕ эти переменные на что-то еще... Не было бы очень хорошо, правильно - особенно, как НЕКОТОРЫЕ этих переменных НЕ нужно менять, потому что переход на 32-битный int для некоторых из вашего кода не будет иметь никакого значения, поэтому не нужно менять эти биты.

Следует отметить, что WCHAR НЕ совпадает с const char - WCHAR является "широким char", поэтому wchar_t является сопоставимым типом.

Итак, в принципе, "определить наш собственный тип" - это способ гарантировать, что можно изменить базовую архитектуру компилятора, не изменяя (большую часть) исходного кода. Все крупные проекты, которые выполняют машинное кодирование, делают такие вещи.

Ответ 2

Размеры и другие характеристики встроенных типов, таких как int и long, могут варьироваться от одного компилятора к другому, обычно в зависимости от базовой архитектуры системы, на которой работает код.

Например, в 16-разрядных системах, на которых первоначально была реализована Windows, int составлял всего 16 бит. В более современных системах int - 32 бита.

Microsoft получает такие типы, как DWORD, чтобы их размеры оставались одинаковыми в разных версиях их компилятора или других компиляторов, используемых для компиляции кода Windows.

И имена предназначены для отражения концепций базовой системы, определенных Microsoft. A DWORD - это "двойное слово" (которое, если я правильно помню, имеет 32 бита в Windows, хотя машинное "слово", вероятно, 32 или даже 64 бита в современных системах).

Возможно, было бы лучше использовать типы фиксированной ширины, определенные в <stdint.h>, такие как uint16_t и uint32_t, но они были введены только на язык C по стандарту ISO ISO 1999 (который Microsoft компилятор не полностью поддерживает даже сегодня).

Если вы пишете код, который взаимодействует с Win32 API, вы должны определенно использовать типы, определенные этим API. Для кода, который не взаимодействует с Win32, используйте любые типы, которые вам нравятся, или любые типы, предлагаемые интерфейсом, который вы используете.

Ответ 3

Я думаю, что это историческая катастрофа.

Моя теория заключается в том, что оригинальные разработчики Windows знали, что стандартные размеры типа C зависят от компилятора, то есть один компилятор может иметь 16-разрядное целое число, а другое 32-разрядное целое. Поэтому они решили сделать API-интерфейс Windows переносимым между разными компиляторами с помощью серии typedefs: DWORD - это 32-разрядное целое без знака, независимо от того, какой компилятор/архитектура вы используете. Естественно, в настоящее время вы будете использовать uint32_t из <stdint.h>, но в то время это было недоступно.

Затем, с помощью элемента UNICODE, они получили проблему TCHAR vs. CHAR vs. WCHAR, но эту другую историю.

И тогда он вышел из-под контроля, и вы получите такие приятные вещи, как typedef void VOID, *PVOID;, которые совершенно бессмысленны.