Monthly Archives: Октябрь 2014

main vs WinMain

Стандарты C и C++ предписывают в качестве точки входа использовать функцию main, которая принимает ноль или два параметра:

int main(void); // можно () в C++
int main(int argc, char *argv[]);

Второй вариант позволяет получить от системы «параметры командной строки», с которыми была вызвана наша программа. Операционные системы могут поддерживать расширенные варианты main с дополнительными параметрами, но это уже не входит в стандарт языка.

С другой стороны, в Microsoft Windows, как обычно, были введены свои порядки. Стандартной точкой входа является функция с именем WinMain, которая имеет следующий прототип:

int WINAPI WinMain
  (
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd
  );

Её параметры нередко вообще не используются приложением, играя роль обеспечения совместимости со старым кодом. С некоторых пор появился другой вариант — wWinMain (см. ссылку на WinMain выше), отличающийся тем, что строка вызова (командная строка) передаётся в формате широких символов (PWSTR — указатель на строку из 16-битных WCHAR).

Для удовлетворения стандарту компиляторы под Windows предоставляют рантайм, включающий реализацию функции WinMain, которая создаёт окно консоли, инициализирует стандартные потоки ввода-вывода и, в свою очередь, вызывает пользовательскую функцию main. Однако, в некоторых случаях, хочется сохранить стандартную точку входа main и, одновременно, не наблюдать под Windows окна консоли. Для этого можно создать отдельную единицу трансляции, содержащую WinMain, которая будет вызывать main, и компилировать код как Win32-проект без консоли.

Для своих проектов я написал такую реализацию WinMain, которая вызывает main второй формы, передавая ей параметры командной строки, преобразованные в кодировку UTF-8 (работает «как обычно», если используются только символы ASCII). Данная реализация использует только Win32 API (впрочем, я не могу сказать, какая требуется версия Windows — предположительно, код должен работать на Windows XP, но проверялось только на Windows 7).

Исходный код в репозитории по ссылке.

Реклама