2009-02-19 91 views
14

以C/C++編寫的Windows GUI應用程序具有'WinMain'作爲入口點(而不是'main')。我對此的理解是,編譯器生成一個'main'函數,由C運行時調用。這個'main'函數爲GUI設置必要的環境並調用'WinMain'(指定實例句柄等)。如何在不使用WinMain的情況下編寫Windows應用程序?

總之,相信控制檯和GUI應用程序啓動時以下面的方式有所不同:

控制檯應用程序: C運行時 - > '主' 功能(手工編碼)

GUI應用: (編譯器生成) - >'WinMain'函數(手工編碼)

我想驗證這種理解,並找出我如何手動編碼Windows只有'主'功能的GUI(即不需要寫'WinMain')。

回答

15

您的理解不正確。除了一些不同的初始化代碼之外,main和WinMain之間的區別是傳遞給它的參數。

主要如下所示:

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

雖然WinMain中是這樣的:

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

事情已經設置這些參數,並撥打電話,這是啓動代碼。在編譯和鏈接程序時,其中一個鏈接器參數是入口點,根據控制檯或GUI應用程序的不同,它將包含一些不同的啓動代碼。

你當然可以編寫自己的啓動代碼,進入你的visual C++源代碼目錄,你可以找到啓動代碼,它叫做crt0.c,它在VC \ crt \ src目錄下。

6

它以另一種方式工作。有一個靜態鏈接的目標文件與編譯器一起提供,它包含實際的入口點。該入口點會進行初始化,然後調用您的入口點(即WinMain)。

該靜態部分期望調用什麼可能是可調整的。例如,在Visual Studio中,鏈接器設置中有一個用於入口點名稱的字段。

+0

那麼控制檯和GUI應用程序的執行順序是什麼?這兩種情況下的靜態部分是不同的? C運行時在哪裏? – 2009-02-19 10:30:49

8

隨着主要,你不能編碼Winmain。對於理由,從 http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

採取的發言之後[在Windows編程,]爲什麼沒有應用程序的入口點稱爲 主?那麼,首先,main的名字已經被佔用,並且Windows沒有權限保留一個備用定義。 當時還沒有C語言標準化委員會; C是 丹尼斯說的是,並且幾乎不能保證丹尼斯 將採取任何特殊步驟來保留任何未來版本的C語言中的Windows源代碼 兼容性。由於K & R 未指定實現可以擴展主函數的可接受形式 ,所以完全有可能存在合法的編譯器,該編譯器拒絕聲明主要不正確的程序。目前的C語言標準明確允許實現特定的 替代定義爲主,但要求所有編譯器支持 這個新的特定於Windows的版本以編譯Windows程序 將無償地限制您可用於編寫的一組編譯器 Windows程序。

如果你成功地克服了這一障礙,你有 的主要的Windows版本必須是這樣的問題:進行

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

由於路C鍵,所有函數的變體必須同意它們共有的參數 。這意味着Windows版本 將不得不將其參數添加到最長版本的主版本的末尾,然後您必須跨越手指並希望 C語言從未添加另一個主版本。如果 你去了這條路線,你的交叉手指失敗了,因爲它會變成 ,第三個參數在一段時間之後被添加到主體中,而它的 與您的Windows友好版本衝突。

假設您設法說服Dennis不允許 的三參數版本的main。您仍然必須想出前兩個參數 ,這意味着每個程序的啓動代碼 都需要包含命令行解析器。早在16位的日子裏, 就被人們排除在外以節省每個字節。告訴他們,「噢,你所有的 節目將會變大2KB」可能不會讓你的朋友很多 。我的意思是,這是四個I/O扇區的軟盤!

但是,爲什麼Windows入口點被賦予了一個 不同的名字,可能是爲了強調它是一個不同的執行環境 。如果它被稱爲main,那麼人們會將C程序 設計爲一個控制檯環境,將它們放入他們的Windows 編譯器中,然後運行它們,併產生災難性結果。

希望這會消除你的疑惑。

相關問題