Как я могу написать приложение для Windows без использования WinMain? - PullRequest
14 голосов
/ 19 февраля 2009

Приложения Windows GUI, написанные на C / C ++, имеют в качестве точки входа «WinMain» (а не «main»). Насколько я понимаю, компилятор генерирует «основную» функцию, которая вызывается средой выполнения C. Эта основная функция устанавливает необходимую среду для графического интерфейса и вызывает WinMain (с указанием дескрипторов экземпляра и т. Д.).

Короче говоря, я считаю, что запуск консоли и приложений с графическим интерфейсом может отличаться следующим образом:

Консольное приложение: C Runtime -> «основная» функция (с ручным кодированием)

Приложение с графическим интерфейсом: C Runtime -> функция 'main' (генерируется компилятором) -> функция 'WinMain' (кодируется вручную)

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

Ответы [ 3 ]

15 голосов
/ 19 февраля 2009

У вас неверное понимание. Разница между main и WinMain, за исключением некоторого другого кода инициализации, заключается в передаваемых ему параметрах.

главное выглядит так:

int main(int argc, char* argv[]);

Пока WinMain выглядит так:

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

Что-то должно настроить эти параметры и сделать вызов, и это код запуска. Когда вы компилируете и связываете программу, одним из параметров компоновщика является точка входа, и в зависимости от консоли или приложения с графическим интерфейсом это будет другой бит кода запуска.

Вы, конечно, можете написать свой собственный код запуска, просто перейдите в исходный каталог Visual C ++ и найдите код запуска, он называется crt0.c и он находится в каталоге VC \ crt \ src.

8 голосов
/ 19 февраля 2009

С помощью Just main вы не можете кодировать Winmain. Для обоснования, следующие заявления были взяты из http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

[В программировании Windows] Почему точка входа приложения не называется главный? Ну, во-первых, имя главное уже было принято, и У Windows не было полномочий резервировать альтернативное определение. Тогда не было комитета по стандартизации языка Си; C был что Деннис сказал, что это было, и вряд ли было гарантировано, что Деннис предпримет какие-то особые шаги для сохранения исходного кода Windows совместимость в любой будущей версии языка C. С K & R не указал, что реализации могут расширять приемлемые формы основной функции, вполне возможно, что существует Компилятор C, который отклонил программы, которые объявили main неправильно. текущий стандарт языка C явно разрешает реализацию альтернативные определения для main, но требующие поддержки всех компиляторов эта новая версия для Windows, предназначенная для компиляции программ для Windows будет безвозмездно ограничивать набор компиляторов, которые вы можете использовать для написание программ для Windows.

Если бы вам удалось преодолеть это препятствие, у вас возникла бы проблема версия main для Windows должна выглядеть примерно так:

int main(int argc, char *argv[], HINSTANCE hinst,
         HINSTANCE hinstPrev, int nCmdShow);

В связи с тем, как выполнялась связь С, все варианты функции должны были согласовываться с Параметры у них были общие. Это означает, что версия для Windows придется добавить свои параметры в конец самого длинного из существующих версия main, и тогда вам придется скрестить пальцы и надеяться что язык C никогда не добавлял другую альтернативную версию main. Если вы пошли по этому пути, ваши скрещенные пальцы подвели вас, потому что он поворачивает выяснилось, что третий параметр был добавлен в main через некоторое время, и это конфликтует с вашей версией для Windows.

Предположим, вам удалось убедить Денниса не допустить этого трехпараметрическая версия основного. Вы все еще должны придумать те первые два параметра, что означает, что код запуска каждой программы должен содержать анализатор командной строки. Назад в 16-битные дни, люди старались сохранить каждый байт. Говоря им: «О, и все ваши программы будут на 2 КБ больше ", вероятно, не сделает вас много друзей. Я имею в виду, что это четыре сектора ввода-вывода с дискеты!

Но, вероятно, причина, по которой точка входа Windows получила другое название, чтобы подчеркнуть, что это другое исполнение среда. Если бы это называлось основным, люди брали бы программы на С предназначен для консольной среды, бросьте их в их Windows компилятор, а затем запустить их с катастрофическими результатами.

Надеюсь, это очистит ваши сомнения.

6 голосов
/ 19 февраля 2009

Работает по-другому. Есть статически связанный объектный файл, который поставляется с компилятором, который содержит фактическую точку входа. Эта точка входа выполняет инициализацию, а затем вызывает вашу точку входа (т.е. WinMain).

То, что ожидает эта статическая часть, может быть изменено. Например, в Visual Studio есть поле для имени точки входа в настройках компоновщика.

...