undefinierter Verweis auf `WinMain@16′

Lesezeit: 7 Minuten

undefinierter Verweis auf WinMain@16
Einfachheit

Wenn ich versuche, ein Programm mit Eclipse CDTbekomme ich folgendes:

/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): undefinierter Verweis auf `WinMain@16

Warum ist das so? Und wie kann ich dieses Problem lösen?

  • Versuchen Sie, Ihre Datei zu speichern und erneut auszuführen, in meinem Fall hat es funktioniert

    – yugsharma1711

    21. März 2021 um 15:09 Uhr

undefinierter Verweis auf WinMain@16
Prost und hth. – Alf

Dieser Fehler tritt auf, wenn der Linker nicht finden kann WinMain Funktion, also fehlt sie wahrscheinlich. In Ihrem Fall fehlen Sie wahrscheinlich main zu.

Betrachten Sie das folgende Programm auf Windows-API-Ebene:

#define NOMINMAX
#include <windows.h>

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

Lassen Sie es uns jetzt mit der GNU-Toolchain (dh g++) erstellen, ohne spezielle Optionen. Hier gnuc ist nur eine Batch-Datei, die ich dafür verwende. Es bietet nur Optionen, um g++ standardisierter zu machen:

C:\test> gnuc x.cpp

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000003        (Windows CUI)

C:\test> _

Das bedeutet, dass der Linker standardmäßig eine erzeugt Konsolen-Subsystem ausführbar. Die Teilsystem Der Wert im Dateiheader teilt Windows mit, welche Dienste das Programm benötigt. In diesem Fall mit Konsolensystem, dass das Programm ein Konsolenfenster benötigt.

Dies bewirkt auch, dass der Befehlsinterpreter auf den Abschluss des Programms wartet.

Jetzt bauen wir es mit GUI-Subsystemwas nur bedeutet, dass das Programm kein Konsolenfenster benötigt:

C:\test> gnuc x.cpp -mwindows

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000002        (Windows GUI)

C:\test> _

Hoffentlich ist das soweit OK, obwohl die -mwindows Flagge ist nur halb dokumentiert.

Ohne dieses halbdokumentierte Flag zu bauen, müsste man dem Linker genauer mitteilen, welchen Subsystemwert man wünscht, und einige Windows-API-Importbibliotheken müssen dann im Allgemeinen explizit angegeben werden:

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

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000002        (Windows GUI)

C:\test> _

Das hat mit der GNU-Toolchain gut funktioniert.

Aber was ist mit der Microsoft-Toolchain, also Visual C++?

Nun, das Erstellen als ausführbare Konsolen-Subsystem-Datei funktioniert gut:

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

C:\test> dumpbin /headers x.exe | find /i "subsystem" | find /i "Windows"
               3 subsystem (Windows CUI)

C:\test> _

Mit Microsofts Toolchain funktioniert das Erstellen als GUI-Subsystem jedoch standardmäßig nicht:

C:\test> msvc x.cpp user32.lib /link /subsystem:windows
x.cpp
LIBCMT.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartu
p
x.exe : fatal error LNK1120: 1 unresolved externals

C:\test> _

Technisch gesehen liegt das am Linker von Microsoft ist standardmäßig kein Standard für das GUI-Subsystem. Wenn das Subsystem eine GUI ist, verwendet der Linker von Microsoft standardmäßig eine Laufzeitbibliothek Einstiegspunktdie Funktion, bei der die Ausführung des Maschinencodes beginnt, aufgerufen winMainCRTStartupdas nennt Microsofts Nicht-Standard WinMain statt Standard main.

Es ist jedoch keine große Sache, das zu beheben.

Alles, was Sie tun müssen, ist, dem Linker von Microsoft mitzuteilen, welchen Einstiegspunkt er verwenden soll, nämlich mainCRTStartupdie Standard aufruft main:

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

C:\test> dumpbin /headers x.exe | find /i "subsystem" | find /i "Windows"
               2 subsystem (Windows GUI)

C:\test> _

Kein Problem, aber sehr mühsam. Und so geheimnisvoll und verborgen, dass die meisten Windows-Programmierer, die meistens nur die Nicht-Standard-Standard-Tools von Microsoft verwenden, nicht einmal davon wissen und fälschlicherweise denken, dass ein Windows-GUI-Subsystem-Programm Nicht-Standard haben „muss“. WinMain statt Standard main. Nebenbei bemerkt, mit C++0x wird Microsoft damit ein Problem haben, da der Compiler dann angeben muss, ob es freistehend oder gehostet ist (wenn es gehostet wird, muss es Standard unterstützen main).

Wie auch immer, das ist der Grund, warum g++ kann beschweren über WinMain fehlt: Es ist eine dumme, nicht standardmäßige Startfunktion, die Microsofts Tools standardmäßig für GUI-Subsystemprogramme benötigen.

Aber wie Sie oben sehen können, hat g++ kein Problem mit Standard main sogar für ein GUI-Subsystemprogramm.

Was könnte also das Problem sein?

Nun, das sind Sie wahrscheinlich fehlen ein main. Und du hast wahrscheinlich keine (richtige) WinMain entweder! Und dann g++, nachdem Sie gesucht haben main (nicht so), und für Microsofts Nicht-Standard WinMain (keine solche), meldet, dass letztere fehlt.

Testen mit einer leeren Quelle:

C:\test> type 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): undefined referen
ce to `WinMain@16'
collect2: ld returned 1 exit status

C:\test> _

  • @Alf P. Steinbach. Vielen Dank für Ihre nette Antwort. Wie für All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main. Gibt es eine Möglichkeit, das zu tun? Eclipse CDT da ich die Befehlszeile nicht verwende. Danke

    – Einfachheit

    10. März 2011 um 14:06 Uhr

  • @ user588855: Da Sie g ++ verwenden, trifft das (wahrscheinlich) nicht auf Sie zu. Nur der Teil am Ende (wahrscheinlich) trifft zu. Das heißt, definiere a main oder ein WinMain, oder stellen Sie sicher, dass die relevante Datei im Projekt enthalten ist. Prost,

    – Prost und hth. – Alf

    10. März 2011 um 14:42 Uhr

  • @Alf P. Steinbach. Was meinst du mit definieren main oder winmain? Danke

    – Einfachheit

    10. März 2011 um 15:07 Uhr

  • @ user588855: Das Beispielprogramm oben in der Antwort zeigt einen Standard main Funktion. Sie brauchen das in Ihrem Programm (aber mit einem anderen Körper). Oder Sie verwenden möglicherweise eine nicht standardmäßige Microsoft WinMainaber Sie müssen eine davon haben, und die Datei muss in das Projekt aufgenommen werden.

    – Prost und hth. – Alf

    10. März 2011 um 16:27 Uhr

  • Ich habe gerade eine Datei namens main.cpp erstellt, die den Code hatte: int main() { }

    – In der Tat

    30. Dezember 2016 um 7:49 Uhr


undefinierter Verweis auf WinMain@16
Tim Ludwinski

Um den obigen Beitrag von Cheers und hth zusammenzufassen. – Alf, stellen Sie sicher, dass Sie es haben main() oder WinMain() definiert und g++ sollte das Richtige tun.

Mein Problem war das main() wurde versehentlich innerhalb eines Namensraums definiert.

  • Ich habe gerade etwas Wichtiges an all dem erkannt. In meinem Fall wurde main() nicht gefunden, da ich keine Argumente (argc, argv) deklariert habe. Einmal hinzugefügt, fand es main. Die Art und Weise, wie dies funktioniert, bedeutet auch, dass mingw versucht, zu helfen, indem es sein eigenes main bereitstellt, das wiederum WinMain aufruft. GUI-Programme hätten nur WinMain und der Hauptstub in mingw wird verwendet, um dorthin zu gelangen. Wenn Sie eine Hauptleitung haben, wird diese stattdessen verwendet.

    – Jeff Muir

    23. März 2016 um 0:53 Uhr

  • extern “C” int main(void) hat das Problem für mich behoben

    – getrockneter

    1. Oktober 2019 um 20:05 Uhr

Dieser Fehler ist beim Kompilieren meiner Anwendung mit SDL aufgetreten. Dies wurde dadurch verursacht, dass SDL seine eigene Main-Funktion in SDL_main.h definierte. Um zu verhindern, dass SDL die Hauptfunktion definiert, muss ein SDL_MAIN_HANDLED-Makro definiert werden, bevor der SDL.h-Header eingefügt wird.

  • Vielen Dank! Dieser Befehl funktioniert: gcc main.c -I”E:\Libs\SDL2-devel-2.0.12-mingw\SDL2-2.0.12\i686-w64-mingw32\include” -I”E:\Libs\SDL2_ttf- devel-2.0.15-mingw\SDL2_ttf-2.0.15\i686-w64-mingw32\include” -L”E:\Libs\SDL2-devel-2.0.12-mingw\SDL2-2.0.12\i686-w64- mingw32\lib” -L”E:\Libs\SDL2_ttf-devel-2.0.15-mingw\SDL2_ttf-2.0.15\i686-w64-mingw32\lib” -lSDL2 -lSDL2main -lSDL2_ttf -o app.exe

    – 8Beobachter8

    3. Mai 2020 um 5:07 Uhr


1647266412 982 undefinierter Verweis auf WinMain@16
JabbaJava

Versuchen Sie, Ihre .c-Datei vor dem Erstellen zu speichern. Ich glaube, Ihr Computer verweist auf einen Pfad zu einer Datei ohne darin enthaltene Informationen.

Meine Situation war, dass ich keine Hauptfunktion hatte.

1647266413 280 undefinierter Verweis auf WinMain@16
Arturo Devesa

Hatte das gleiche Problem. Um das Problem zu beheben, habe ich auf Speichern geklickt, um meine .c-Datei vor dem Erstellen zu speichern. Ich glaube, mein Computer hat auf einen Pfad zu einer Datei verwiesen, in der sich keine Informationen befinden.

Überprüfen Sie, ob alle Dateien in Ihrem Projekt enthalten sind:

Ich hatte denselben Fehler, nachdem ich cLion aktualisiert hatte. Nach stundenlangem Tüfteln ist mir aufgefallen, dass eine meiner Dateien nicht im Projektziel enthalten war. Nachdem ich es wieder dem aktiven Projekt hinzugefügt hatte, bekam ich keine undefinierte Referenz mehr auf winmain16 und der Code wurde kompiliert.

Bearbeiten: Es lohnt sich auch, die Build-Einstellungen in Ihrer IDE zu überprüfen.

(Nicht sicher, ob dieser Fehler damit zusammenhängt, dass die IDE kürzlich aktualisiert wurde – könnte kausal oder einfach korrelierend sein. Fühlen Sie sich frei, mit Erkenntnissen zu diesem Faktor einen Kommentar abzugeben!)

1001870cookie-checkundefinierter Verweis auf `WinMain@16′

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy