Неопределенная ссылка на `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 - может быть причинной или просто корреляционной. Не стесняйтесь комментировать, какое-либо понимание этого фактора!)