Страницы

Поиск по вопросам

воскресенье, 14 апреля 2019 г.

Как использовать main() вместо WinMain?

Я хочу написать GUI приложение для Windows, но мне не нравится что MS Visual Studio для этого надо писать WinMain. Хочу писать привычную main() или main(argc, argv) - как это сделать?


Ответ

Прежде всего надо понимать, что ни main(), ни WinMain() - не являются "точками входа" .exe файла. Точкой входа (entry point) является некоторая функция, которая будет вызвана операционной системой при старте приложения. В С++ это функция рантайма (CRT), которая проводит инициализацию CRT, вызывает конструкторы глобальных объектов, и затем уже вызывает main или WinMain
Линкеру передается параметр /subsystem, который задает тип приложения, например /SUBSYSTEM:WINDOWS для GUI приложений, или /SUBSYSTEM:CONSOLE для консольных приложений. В первую очередь это нужно операционной системе - тип приложения прописывается в заголовке .exe файла, и по нему ОС понимает надо ли создавать окно консоли, или нет. Также, при помощи этого параметра линкер выбирает точку входа, которая будет использована по-умолчанию
mainCRTStartup (илиwmainCRTStartup) - при использовании /SUBSYSTEM:CONSOLE. Вызывает main (или wmain) WinMainCRTStartup (или wWinMainCRTStartup) - при использовании /SUBSYSTEM:WINDOWS. Вызывает WinMain (или wWinMain).
Точку входа можно переопределить, передав линкеру параметр /entry. Для того чтобы использовать main в GUI приложении, мы должны вызвать линкер с параметрами /SUBSYSTEM:WINDOWS и /ENTRY:mainCRTStartup. Тогда ОС не будет создавать окно консоли, а CRT будет вызывать функцию main
Значение параметра /entry можно переопределить в опциях проекта MSVS (linker > advanced > entry point). Либо его можно написать прямо в коде программы, с помощью pragma comment
#include #pragma comment(linker, "/entry:mainCRTStartup") int main() { ::MessageBoxW(nullptr, L"(^._.^)", L"Important message", MB_OK); }

Комментариев нет:

Отправить комментарий