Kiedy próbuję zbudować program przy użyciu Eclipse CDT
, otrzymuję:
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): niezdefiniowane odniesienie do `WinMain @ 16
Dlaczego? Jak mogę rozwiązać ten problem?
źródło
Kiedy próbuję zbudować program przy użyciu Eclipse CDT
, otrzymuję:
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): niezdefiniowane odniesienie do `WinMain @ 16
Dlaczego? Jak mogę rozwiązać ten problem?
Rozważmy następujący program na poziomie interfejsu API systemu Windows:
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
Teraz zbudujmy go używając GNU toolchain (tj. G ++), bez specjalnych opcji. Oto gnuc
tylko plik wsadowy, którego używam do tego. Dostarcza tylko opcje zwiększające standard g ++:
C: \ test> gnuc x.cpp C: \ test> objdump -x a.exe | findstr / i "^ podsystem" Podsystem 00000003 (Windows CUI) C: \ test> _
Oznacza to, że konsolidator domyślnie utworzył plik wykonywalny podsystemu konsoli . Wartość podsystemu w nagłówku pliku mówi systemowi Windows, jakich usług wymaga program. W tym przypadku, z systemem konsoli, program wymaga okna konsoli.
Powoduje to również, że interpreter poleceń czeka na zakończenie programu.
Teraz zbudujmy go z podsystemem GUI , co oznacza po prostu, że program nie wymaga okna konsoli:
C: \ test> gnuc x.cpp -mwindows C: \ test> objdump -x a.exe | findstr / i "^ podsystem" Podsystem 00000002 (GUI systemu Windows) C: \ test> _
Miejmy nadzieję, że jak dotąd jest to w porządku, chociaż -mwindows
flaga jest tylko częściowo udokumentowana.
Budując bez tej częściowo udokumentowanej flagi, należałoby dokładniej powiedzieć konsolidatorowi, jakiej wartości podsystemu chce, a niektóre biblioteki importu API systemu Windows będą musiały być ogólnie określone jawnie:
C: \ test> gnuc x.cpp -Wl, -subsystem, windows C: \ test> objdump -x a.exe | findstr / i "^ podsystem" Podsystem 00000002 (GUI systemu Windows) C: \ test> _
To działało dobrze z łańcuchem narzędzi GNU.
Ale co z łańcuchem narzędzi Microsoft, czyli Visual C ++?
Cóż, budowanie jako plik wykonywalny podsystemu konsoli działa dobrze:
C: \ test> msvc x.cpp user32.lib x.cpp C: \ test> dumpbin / headers x.exe | znajdź / i "podsystem" | find / i "Windows" 3 podsystem (Windows CUI) C: \ test> _
Jednak z budowaniem łańcucha narzędzi firmy Microsoft jako podsystemu GUI nie działa domyślnie:
C: \ test> msvc x.cpp user32.lib / link / subsystem: windows x.cpp LIBCMT.lib (wincrt0.obj): błąd LNK2019: nierozwiązany symbol zewnętrzny _WinMain @ 16, do którego odwołuje się funkcja ___tmainCRTStartu p x.exe: błąd krytyczny LNK1120: 1 nierozwiązane zewnętrzne C: \ test> _
Technicznie jest to spowodowane tym, że konsolidator Microsoftu jest domyślnie niestandardowy dla podsystemu GUI . Domyślnie, gdy podsystemem jest GUI, wówczas konsolidator Microsoftu używa punktu wejścia biblioteki środowiska wykonawczego , funkcji, w której rozpoczyna się wykonywanie kodu maszynowego, nazywanej winMainCRTStartup
, która wywołuje niestandardowy WinMain
zamiast standardowego Microsoft main
.
Jednak nic wielkiego, żeby to naprawić.
Wszystko, co musisz zrobić, to powiedzieć linkerowi Microsoftu, którego punktu wejścia użyć, a mianowicie mainCRTStartup
, który wywołuje standard main
:
C: \ test> msvc x.cpp user32.lib / link / subsystem: windows / entry: mainCRTStartup x.cpp C: \ test> dumpbin / headers x.exe | znajdź / i "podsystem" | find / i "Windows" 2 podsystem (GUI Windows) C: \ test> _
Żaden problem, ale bardzo uciążliwy. I tak tajemniczy i ukryty, że większość programistów Windows, którzy przeważnie używają tylko niestandardowych narzędzi Microsoftu, nawet o tym nie wie i błędnie myśli, że program podsystemu GUI Windows „musi” mieć niestandardowy WinMain
zamiast standardowego main
. Na marginesie, z C ++ 0x Microsoft będzie miał z tym problem, ponieważ kompilator musi następnie ogłosić, czy jest wolnostojący, czy hostowany (gdy jest hostowany, musi obsługiwać standard main
).
W każdym razie, to jest powód, dla którego g ++ może narzekać, że WinMain
brakuje: jest to głupia niestandardowa funkcja startowa, której narzędzia Microsoftu wymagają domyślnie dla programów podsystemu GUI.
Ale jak widać powyżej, g ++ nie ma problemu ze standardem main
nawet dla programu podsystemu GUI.
Więc jaki może być problem?
Cóż, prawdopodobnie brakuje ci main
. I prawdopodobnie nie masz też (właściwego) WinMain
! A potem g ++, po wyszukaniu main
(nie takiego) i niestandardowego Microsoft WinMain
(nie takiego), zgłasza, że brakuje tego ostatniego.
Testowanie z pustym źródłem:
C: \ test> wpisz nul> y.cpp C: \ test> gnuc y.cpp -mwindows c: / program files / mingw / bin /../ lib / gcc / mingw32 / 4.4.1 /../../../ libmingw32.a (main.o): main.c :(. text + 0xd2 ): niezdefiniowane odwołanie ce do `` WinMain @ 16 '' collect2: ld zwrócił 1 status wyjścia C: \ test> _
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main
. Czy istnieje sposób, aby to zrobić,Eclipse CDT
ponieważ nie używam wiersza poleceń. Dziękimain
lub aWinMain
, lub upewnij się, że odpowiedni plik jest uwzględniony w projekcie. Pozdrawiam,main
lubwinmain
? DziękiPodsumowując powyższy post przez Cheers i hth. - Alf, Upewnij się, że masz
main()
lubWinMain()
zdefiniowałeś, a g ++ powinno zrobić właściwą rzecz.Mój problem polegał na tym, że
main()
zostało to przypadkowo zdefiniowane w przestrzeni nazw.źródło
Wystąpił ten błąd podczas kompilowania mojej aplikacji z SDL. Było to spowodowane definiowaniem przez SDL swojej własnej głównej funkcji w SDL_main.h. Aby uniemożliwić SDL zdefiniowanie głównej funkcji, przed dołączeniem nagłówka SDL.h należy zdefiniować makro SDL_MAIN_HANDLED.
źródło
Spróbuj zapisać plik .c przed rozpoczęciem budowania. Wydaje mi się, że Twój komputer odwołuje się do ścieżki do pliku, który nie zawiera żadnych informacji.
- Miałem podobny problem podczas tworzenia projektów C.
źródło
Sprawdź, czy wszystkie pliki są zawarte w Twoim projekcie:
Ten sam błąd pojawił się po aktualizacji cLion. Po godzinach majsterkowania zauważyłem, że jeden z moich plików nie został uwzględniony w celu projektu. Po dodaniu go z powrotem do aktywnego projektu, przestałem pobierać niezdefiniowane odwołanie do winmain16 i skompilowałem kod.
Edycja: warto również sprawdzić ustawienia kompilacji w swoim IDE.
(Nie jestem pewien, czy ten błąd jest związany z niedawną aktualizacją IDE - może być przyczynowy lub po prostu skorelowany. Zapraszam do komentowania z wszelkimi spostrzeżeniami na temat tego czynnika!)
źródło