Неопределенная ссылка на `WinMain@16'

Когда я пытаюсь построить программу, используя Eclipse CDTЯ получаю следующее:

/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): неопределенная ссылка на `WinMain@16

Это почему? И как я могу решить эту проблему?

7 ответов

Рассмотрим следующую программу уровня API Windows:

#define NOMINMAX
#include <windows.h>

int main()
{
    MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}

Теперь давайте создадим его, используя цепочку инструментов GNU (т.е. g++), без специальных опций. Вот gnuc это просто командный файл, который я использую для этого. Он только предоставляет опции, чтобы сделать g ++ более стандартным:

C: \ test> gnuc x.cpp

C: \ test> objdump -x a.exe | findstr / i "^ подсистема"
Подсистема 00000003 (Windows CUI)

C:\test> _

Это означает, что компоновщик по умолчанию создал исполняемый файл консольной подсистемы. Значение подсистемы в заголовке файла говорит Windows, какие сервисы требуются программе. В этом случае с консольной системой эта программа требует консольного окна.

Это также заставляет интерпретатор команд ожидать завершения программы.

Теперь давайте создадим его с подсистемой GUI, что означает, что программе не требуется окно консоли:

C: \ test> gnuc x.cpp -mwindows

C: \ test> objdump -x a.exe | findstr / i "^ подсистема"
Подсистема 00000002 (Windows GUI)

C:\test> _

Надеюсь, что пока все нормально, хотя -mwindows флаг просто полу-документально.

При построении без этого полу-документированного флага нужно было бы более конкретно указать компоновщику, какую подсистему желать получить одно значение, и тогда в общем случае некоторые библиотеки импорта Windows API нужно будет явно указать:

C: \ test> gnuc x.cpp -Wl, -subsystem, windows

C: \ test> objdump -x a.exe | findstr / i "^ подсистема"
Подсистема 00000002 (Windows GUI)

C:\test> _

Это работало нормально, с набором инструментов GNU.

Но как насчет набора инструментов Microsoft, то есть Visual C++?

Хорошо, сборка исполняемого файла консольной подсистемы работает нормально:

C: \ test> msvc x.cpp user32.lib
x.cpp

C: \ test> dumpbin / headers x.exe | найти / я "подсистема" | найти / я "Windows"
               3 подсистема (Windows CUI)

C:\test> _

Тем не менее, при построении набора инструментов Microsoft в качестве подсистемы GUI по умолчанию не работает:

C: \ test> msvc x.cpp user32.lib / link / subsystem: windows x.cpp LIBCMT.lib (wincrt0.obj): ошибка LNK2019: неразрешенный внешний символ _WinMain@16, указанный в функции ___tmainCRTStartu
p
x.exe: неисправимая ошибка LNK1120: 1 неразрешенный внешний вид C:\test> _ 

Технически это происходит потому, что компоновщик Microsoft является нестандартным по умолчанию для подсистемы GUI. По умолчанию, когда подсистема имеет GUI, компоновщик Microsoft использует точку входа в библиотеку времени выполнения, функцию, с которой начинается выполнение машинного кода, и называется winMainCRTStartup, что называет Microsoft нестандартным WinMain вместо стандартного main,

Ничего страшного, чтобы исправить это, хотя.

Все, что вам нужно сделать, это сообщить компоновщику Microsoft, какую точку входа использовать, а именно mainCRTStartup, который называет стандарт main:

C: \ test> msvc x.cpp user32.lib / link / subsystem: windows / entry: mainCRTStartup
x.cpp

C: \ test> dumpbin / headers x.exe | найти / я "подсистема" | найти / я "Windows"
               2 подсистема (Windows GUI)

C:\test> _

Нет проблем, но очень утомительно. И настолько загадочные и скрытые, что большинство программистов Windows, которые в основном используют только нестандартные инструменты Microsoft по умолчанию, даже не знают об этом и ошибочно полагают, что программа подсистемы Windows GUI "должна" иметь нестандартные WinMain вместо стандартного main, Попутно, с C++0x у Microsoft возникнет проблема с этим, поскольку компилятор должен затем объявить, является ли он автономным или размещенным (при размещении он должен поддерживать стандартный main).

Во всяком случае, это причина, почему G ++ может жаловаться на WinMain отсутствует: это глупая нестандартная функция запуска, которая требуется инструментам Microsoft по умолчанию для программ подсистемы GUI.

Но, как вы можете видеть выше, у g ++ нет проблем со стандартными main даже для программы с графическим интерфейсом.

Так в чем может быть проблема?

Ну, вы, вероятно, скучаете по main, И у вас, вероятно, нет (собственно) WinMain или! И затем g++, после поиска main (нет такого), а для Microsoft нестандартный WinMain (нет такого), сообщает, что последний отсутствует.

Тестирование с пустым источником:

C: \ test> введите nul> y.cpp

C: \ test> gnuc y.cpp -mwindows
c: / программные файлы /mingw/bin/../lib/gcc/mingw32/4.4.1/../../../libmingw32.a(main.o):main.c:(.text+0xd2): неопределенная ссылка
ce в `WinMain@16'
collect2: ld вернул 1 статус выхода

C:\test> _

Подведем итог вышеприведенному посту Cheers и hth. - Альф, убедитесь, что у вас есть main() или же WinMain() определены и G ++ должен делать правильные вещи.

Моя проблема была в том, что main() был определен внутри пространства имен случайно.

Я столкнулся с этой ошибкой при компиляции моего приложения с SDL. Это было вызвано тем, что SDL определил свою собственную основную функцию в SDL_main.h. Чтобы предотвратить SDL, определите основную функцию, макрос SDL_MAIN_HANDLED должен быть определен до включения заголовка SDL.h.

Попробуйте сохранить ваш файл.c перед сборкой. Я считаю, что ваш компьютер ссылается на путь к файлу без информации внутри него.

- Была похожая проблема при создании проектов C

Моя ситуация заключалась в том, что у меня не было основной функции.

Была такая же проблема. Чтобы исправить это, я нажал кнопку «Сохранить», чтобы сохранить файл .c перед сборкой. Я считаю, что мой компьютер ссылался на путь к файлу без информации внутри него.

Убедитесь, что все файлы включены в ваш проект:

У меня была такая же ошибка после обновления cLion. После нескольких часов возня я заметил, что один из моих файлов не был включен в цель проекта. После того, как я добавил его обратно в активный проект, я перестал получать неопределенную ссылку на winmain16, и код компилировался.

Изменить: также стоит проверить настройки сборки в вашей среде IDE.

(Не уверен, связана ли эта ошибка с недавним обновлением IDE - может быть причинной или просто корреляционной. Не стесняйтесь комментировать, какое-либо понимание этого фактора!)

Другие вопросы по тегам