2009-02-19 12 views
14

Aplikacje Windows GUI napisane w C/C++ mają "WinMain" jako punkt wejścia (a nie "główny"). Moje rozumienie tego jest takie, że kompilator generuje funkcję "główną", która ma być wywołana przez środowisko wykonawcze C. Ta "główna" funkcja ustawia niezbędne środowisko dla GUI i wywołuje "WinMain" (określając uchwyty instancji itp.).Jak napisać aplikację Windows bez użycia WinMain?

Krótko mówiąc, uważam, że konsola i uruchamiania aplikacji GUI różnią się w sposób następujący:

Console zastosowanie: C Runtime -> 'main' function (ręcznie kodowane) aplikacja

GUI: C Runtime -> funkcja "główna" (generowana przez kompilator) -> Funkcja "WinMain" (kodowane ręcznie)

Chciałbym potwierdzić to zrozumienie i dowiedzieć się, w jaki sposób mogę ręcznie kodować system Windows GUI z tylko "główną" funkcją (tj. Bez konieczności pisania "WinMain").

Odpowiedz

15

Masz nieprawidłowe zrozumienie. Różnica między głównym a WinMain, oprócz kodu inicjującego różnicowanie, to parametry przekazane do niego.

główne wygląda następująco:

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

Podczas WinMain wygląda następująco:

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

Coś musi skonfigurować te parametry i nawiązać połączenie, i to jest kod startowy. Podczas kompilacji i łączenia programów jednym z parametrów linkera jest punkt wejścia, który będzie, w zależności od konsoli lub aplikacji GUI, innym bitem kodu startowego.

Z pewnością możesz napisać swój własny kod startowy, po prostu przejdź do swojego wizualnego katalogu źródłowego C++ i możesz znaleźć kod startowy, nazywa się to crt0.c i znajduje się w katalogu VC \ crt \ src.

6

Działa w drugą stronę. Istnieje statycznie połączony plik obiektowy, który jest dostarczany z kompilatorem, który przechowuje faktyczny punkt wejścia. Ten punkt wejścia inicjuje, a następnie wywołuje punkt wejścia (np. WinMain).

To, czego ta część statyczna oczekuje, może zostać zmodyfikowane. Na przykład w Visual Studio jest pole dla nazwy punktu wejścia w ustawieniach linkera.

+0

Jaka jest kolejność wykonywania w przypadku konsoli i aplikacji GUI? Czy część statyczna różni się w tych dwóch przypadkach? Gdzie znajduje się środowisko wykonawcze C? –

+0

Najpierw wykonuje się część statyczną, a następnie wywołuje zaimplementowany przez użytkownika punkt wejścia. Może być różny lub może być taki sam, ale linker może łączyć wywołanie z różnymi punktami wejścia w zależności od ustawień. Możesz myśleć o tej statycznej części, ponieważ jest ona częścią środowiska wykonawczego C. – sharptooth

8

Po prostu nie można kodować Winmain. Dla uzasadnienia, następujące oświadczenia zostały zaczerpnięte z http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

[W systemie Windows Programming] Dlaczego nie punkt wejścia aplikacja nazywa główny? Po pierwsze, nazwa główna została już zajęta, a system Windows nie miał uprawnień do rezerwowania alternatywnej definicji. Nie było wtedy komitetu normalizacyjnego w języku C; C było , co Dennis powiedział, że było, i nie można było zagwarantować, że Dennis podejmie specjalne kroki w celu zachowania kompatybilności kodu źródłowego Windows w dowolnej przyszłej wersji języka C. Ponieważ K & R nie określił, że implementacje mogą rozszerzyć akceptowalne formularze głównej funkcji, było całkowicie możliwe, że istnieje legalny kompilator C C, który odrzucał programy, które zadeklarowały główne niepoprawnie.Standardowy język prąd C wyraźnie zezwala wdrożeniowe specyficzne alternatywne definicje głównym, ale wymagająca wszystkie kompilatory wspierać ten nowy Windows konkretnej wersji w celu opracowania programów Windows byłby nieuzasadniony ograniczać zestaw kompilatorów można użyć do piśmie Programy systemu Windows.

Jeśli udało się pokonać tę przeszkodę, to masz problem, że wersja Windows główny musiałoby być coś takiego:

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

Ze względu na sposób wiązania C przeprowadzono wszystkie warianty funkcji musiały się zgadzać ze wspólnymi parametrami. Oznacza to, że wersja Windows musiałaby dodać swoje parametry na końcu najdłużej istniejącej wersji głównej, a następnie musiałbyś przeciąć palcami i mieć nadzieję, że w języku C nigdy nie dodano kolejnej alternatywnej wersji głównej. Jeśli podążyłeś tą trasą, twoje skrzyżowane palce cię zawiodły, ponieważ okazało się, że trzeci parametr został później dodany do głównej wersji i to kolidowało z wersją przyjazną dla Windows.

Załóżmy, że udało ci się przekonać Dennisa, aby nie zezwolił na trzyparametrową wersję głównej wersji. Nadal musisz wymyślić te dwa pierwsze parametry, co oznacza, że ​​kod startowy każdego programu musi zawierać parser wiersza poleceń. Powrót w 16-bitowych dniach, ludzi skakało, aby zapisać każdy bajt. Mówiąc im "Och, a wszystkie twoje programy będą większe o 2KB" prawdopodobnie nie sprawiłoby Ci wiele znajomych. Mam na myśli to, że cztery sektory wejścia/wyjścia z dyskietki!

Ale prawdopodobnie powodem, dla którego punkt wejścia systemu Windows otrzymał inną nazwę , jest podkreślenie, że jest to środowisko wykonawcze inne niż środowisko wykonawcze . Jeśli byłby nazywany głównym, ludzie mogliby pobrać programy w języku C zaprojektowane dla środowiska konsoli, wrzucić je do swojego kompilatora Windows , a następnie uruchomić je z katastrofalnymi rezultatami.

Mam nadzieję, że rozwiąże to Twoje wątpliwości.

Powiązane problemy