2009-02-19 7 views
14

Windows-GUI-Anwendungen, die in C/C++ geschrieben sind, haben 'WinMain' als Einstiegspunkt (anstatt 'main'). Ich verstehe das so, dass der Compiler eine Hauptfunktion erzeugt, die von der C-Runtime aufgerufen werden kann. Diese 'Haupt'-Funktion richtet die notwendige Umgebung für die GUI ein und ruft' WinMain 'auf (unter Angabe der Instanz-Handles etc.).Wie kann ich eine Windows-Anwendung ohne WinMain schreiben?

Kurz gesagt, ich glaube, Konsole und GUI Start der Anwendung in der folgenden Art und Weise zu unterscheiden:

Konsolenanwendung: C Runtime -> 'main' Funktion (Hand-kodiert)

GUI-Anwendung: C Runtime -> 'main' Funktion (Compiler-generiert) -> 'WinMain' Funktion (handcodiert)

Ich möchte sowohl dieses Verständnis zu validieren und herauszufinden, wie ich ein Windows-Hand-Code GUI mit nur einer 'Hauptfunktion' (dh ohne 'WinMain' schreiben zu müssen).

Antwort

15

Sie haben ein falsches Verständnis. Der Unterschied zwischen main und WinMain besteht, abgesehen von einigen abweichenden Initialisierungscodes, in den Parametern, die an ihn übergeben werden.

Haupt sieht wie folgt aus:

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

Während WinMain wie folgt aussieht:

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

Etwas Setup hat diese Parameter und den Anruf tätigen, und das ist der Startcode. Wenn Sie ein Programm kompilieren und verknüpfen, ist einer der Linker-Parameter der Einstiegspunkt, der abhängig von einer Konsole oder einer GUI-Anwendung einen anderen Startcode enthält.

Sie können sicherlich Ihren eigenen Startup-Code schreiben, gehen Sie einfach in Ihr visuelles C++ - Quellverzeichnis und Sie können den Startup-Code finden, er heißt crt0.c und befindet sich im Verzeichnis VC \ crt \ src.

6

Es funktioniert in die andere Richtung. Es gibt eine statisch verknüpfte Objektdatei, die mit dem Compiler geliefert wird, der den tatsächlichen Einstiegspunkt enthält. Dieser Einstiegspunkt führt die Initialisierung durch und ruft dann Ihren Einstiegspunkt (d. H. WinMain) auf.

Was dieser statische Teil erwartet, kann möglicherweise geändert werden. In Visual Studio gibt es beispielsweise ein Feld für den Namen des Einstiegspunkts in den Linkereinstellungen.

+0

Was ist die Reihenfolge der Ausführung in den Konsolen- und GUI-Anwendungsfällen? Ist der statische Teil in diesen beiden Fällen unterschiedlich? Wo passt die C-Laufzeit? –

+0

Zuerst wird der statische Teil ausgeführt, dann wird der vom Benutzer implementierte Einstiegspunkt aufgerufen. Es kann unterschiedlich sein oder es kann dasselbe sein, aber der Linker könnte den Anruf abhängig von den Einstellungen mit verschiedenen Einstiegspunkten verknüpfen. Sie können sich diesen statischen Teil vorstellen, da er Teil der C-Laufzeit ist. – sharptooth

8

Mit Just main können Sie Winmain nicht codieren. Für Rechtfertigungen, Nach Aussagen von http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

genommen wurden [In Windows Programmierung,] Warum nicht die Anwendung Einstiegspunkt wurde genannt Haupt? Nun, zum einen wurde der Name main bereits vergeben, und Windows hatte nicht die Berechtigung, eine alternative Definition zu reservieren. Damals gab es noch kein C-Standardisierungskomitee; C war , was Dennis sagte, dass es war, und es war kaum garantiert, dass Dennis irgendwelche speziellen Schritte unternehmen würde, um Windows-Quellcode Kompatibilität in jeder zukünftigen Version der C-Sprache zu erhalten. Da K & R nicht angegeben hat, dass Implementierungen die akzeptablen Formulare der Hauptfunktion erweitern könnten, war es durchaus möglich, dass es einen legalen C-Compiler gab, der Programme ablehnte, die main falsch deklarierten.Der aktuelle C-Sprachen-Standard erlaubt explizit implementierungsspezifische alternative Definitionen für main, aber alle Compiler müssen unterstützen diese neue Windows-spezifische Version, um Windows-Programme zu kompilieren würde die Menge der Compiler, die Sie für schreiben können, kostenlos einschränken Windows-Programme.

Wenn Sie dieses Hindernis zu überwinden verwaltet, würden Sie das Problem, dass die Windows-Version von Haupt wäre, so etwas sein:

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

Durch die Verknüpfung Weg C durchgeführt wurde, werden alle Variationen einer Funktion mussten sich auf die gemeinsamen Parameter der -Parameter einigen. Das bedeutet, dass die Windows-Version ihre Parameter am Ende der längsten bestehenden Version von main hinzufügen müsste, und dann müssten Sie die Daumen drücken und hoffen, dass die C-Sprache nie eine andere alternative Version von main hinzugefügt hat. Wenn Sie diese Route gegangen sind, haben Sie Ihre gekreuzten Finger fehlgeschlagen, weil es aus, dass ein dritter Parameter einige Zeit später hinzugefügt wurde, und es im Konflikt mit Ihrer Windows-freundlichen Version.

Angenommen, Sie haben es geschafft, Dennis davon zu überzeugen, diese Drei-Parameter-Version von Haupt zu erlauben. Sie müssen immer noch mit den ersten zwei Parametern kommen, was bedeutet, dass der Startup-Code jedes Programms einen Befehlszeilenparser enthalten muss. Zurück in den 16-Bit-Tagen, Menschen gedrängt, um jedes Byte zu speichern. Ihnen zu sagen, "Oh, und alle Ihre Programme werden 2KB größer sein" würde Sie wahrscheinlich nicht viel von Freunden machen. Ich meine, das sind vier I/O-Bereiche von einer Diskette!

Aber wahrscheinlich der Grund, warum der Windows-Einstiegspunkt einen anderen Namen gegeben wurde, ist zu betonen, dass es eine andere Ausführung Umgebung ist. Wenn es Main genannt würde, würden Leute C-Programme nehmen, die für eine Konsolenumgebung entworfen sind, sie in ihren Windows Compiler werfen und sie dann mit katastrophalen Ergebnissen ausführen.

Hoffe das löscht Ihre Zweifel.

Verwandte Themen