Почему WinAPI так сильно отличается от "нормального" C? - PullRequest
5 голосов
/ 02 декабря 2009

Интересно, почему WinAPI так сильно отличается от "нормального" программирования на C?

Я имею в виду, что в школе я узнал, что в каждой программе на С есть функция main () (WinAPI использует WinMain с некоторыми специальными параметрами), некоторые типы переменных, такие как int, long, char и т. Д. (WinAPI использует такие вещи, как LPCSTR, BOOL, и т.д.), так почему Microsoft решила пойти по-другому с их OS API?

Когда я увидел свою первую программу WinAPI, она стала для меня больше похожа на новый язык ...;)

Ответы [ 6 ]

15 голосов
/ 02 декабря 2009

Оригинальный Windows API был разработан в период 1984-85 годов, более 25 лет назад. Венгерская нотация была в моде, поэтому нужно было добавить тип переменной в объявление. Например, в чистом C нет никакого способа указать «дальний» указатель, как указывает LP в LPCSTR, но в 1985 году было очень важно различать обычные и дальние указатели. (Это значение ушло на второй план, когда 32-битные окна вступили во владение в середине 90-х, но синтаксис сохраняется ...)

Кроме того, C на самом деле не различает только указатель на символ и указатель на статическую строку. Таким образом, типы LPSZ.

В конце концов, речь идет о введении более строгой и согласованной типизации параметров, чем обычная C, разрешенная в 1984 году. Что касается WinMain, то это потому, что программа для Windows довольно сильно отличается от программы командной строки. Если вы заглянете в библиотеку, вы, вероятно, найдете функцию main (), которая устанавливает параметры и затем вызывает внешнюю функцию WinMain (т.е. вашу).

4 голосов
/ 02 декабря 2009

Есть две основные причины:

  • Сложность. Язык Си минимален, предоставляя строительные блоки, на которых могут быть построены более сложные архитектуры. LPCSTR, BOOL и другие типы, которые вы найдете в Win32, являются typedefs или структурами, построенными поверх C.
  • Ориентация на событие. C обычно учат, предполагая, что ваша программа активна и контролирует вещи. В среде, ориентированной на события, такой как Windows (или любая другая ОС на основе графического интерфейса), ваша программа называется ОС, поэтому она обычно находится в цикле, ожидая прибытия сообщений.

API других ОС на основе графического интерфейса могут отличаться от Win32, поскольку единого решения не существует, но проблема, которую они решают, та же.

2 голосов
/ 02 декабря 2009

Microsoft Raymand Chen пишет в своем блоге :

Хотя функция WinMain есть задокументировано в Platform SDK, это не совсем часть платформы. Скорее, WinMain является обычным имя для предоставленной пользователем точки входа в программу Windows.

Реальная точка входа в C библиотека времени выполнения, которая инициализирует время выполнения, запускает глобальные конструкторы и затем вызывает вашу функцию WinMain (или wWinMain, если вы предпочитаете Unicode запись точка).

1 голос
/ 02 декабря 2009

Я бы сказал, что в большинстве случаев это вопрос стиля. Стандарты выросли из мира Unix, так что, например, функции библиотеки имеют короткие имена, и здесь не так много определений типов. Я предполагаю, что это отражает выбор дизайнеров C и Unix. С другой стороны, Windows имеет LongFunctionNamesInMixedCase и LOTSOFTYPEDEFS, *PTYPEDEFSFORPOINTERSTOO.

Отчасти это также восприятие необходимости. Например, WinMain() имеет такие вещи, как nCmdShow, потому что графические приложения будут вызывать ShowWindow(), и я предполагаю, что они хотели бы передать аргумент этому во вновь запущенный процесс. Является ли это на самом деле необходимым , может быть другим вопросом.

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

1 голос
/ 02 декабря 2009

Они действительно не "пошли по-другому", как вы выразились.

WinMain () - это просто точка входа, которую ищет ОС Windows. Концептуально он ничем не отличается от main ().

Что касается определений символов (LPCSTR, BOOL и т. Д.), То часть этого предназначена для простоты использования. Например, написать LPCSTR короче, чем const char *. Другой пример - typedef BOOL, который не поддерживается языком C. Другая причина заключается в том, чтобы изолировать разработчика от изменений в базовом оборудовании, например, при переходе с 16-разрядных на 32-разрядные и 64-разрядные архитектуры.

Ни в коем случае этот ответ не следует считать исчерпывающим. Это всего лишь пара вещей, которые я заметил по программированию на Win32 / MFC.

0 голосов
/ 02 декабря 2009

Программирование Windows API основано на событиях, в то время как до этого момента большинство программ на C были линейными. Таким образом, WinMain () является ярлыком для библиотек для записи с использованием функциональных возможностей ОС, тогда как main () является частью языка C.

Пока мы говорим на эту тему, C имеет мало встроенных типов, и в то время было мало способов их указать. «Типы» окон (HWND, LPSTR, BOOL и т. Д.) Отражают типы данных, обычно используемые при программировании окон, и делают попытку указать программисту, какими будут типы данных.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...