解析 Qt 在 Windows 下入口函數(shù)實(shí)現(xiàn)實(shí)例
Qt 在 Windows 下入口函數(shù)實(shí)現(xiàn)實(shí)例是本文介紹的內(nèi)容。Windows下入口函數(shù) 有 main 和 WinMain 兩種(還有其對應(yīng)的 Unicode 版本,此處不考慮)。一般來說,前者是 控制臺程序 的入口函數(shù),后者是 GUI 程序的入口函數(shù)。
Qt下只有 main?
Qt 是C++ 的庫,它也改變不了 main 和 WinMain 兩種入口函數(shù)的事實(shí);但實(shí)際中,我們在 Qt 程序中只寫main函數(shù),而從不寫WinMain函數(shù)。這是怎么回事呢?
WinMain
當(dāng)我們將 Windows 版的Qt裝好以后,在其lib目錄內(nèi),會發(fā)現(xiàn)兩個(gè)庫:qtmain.lib 和 qtmaind.lib(或者 libqtmain.a和 libqtmaind.a)
很容易判斷,這兩個(gè)庫是同一個(gè)東西(帶d的是debug版,不帶的是release版),所以我們下面可以稱其為一個(gè)庫。那么這一個(gè)庫有什么用呢?
如果細(xì)心的話,我們會發(fā)現(xiàn):當(dāng)我們的pro文件內(nèi) 不指定 CONFIG += console (而且也不使用 qtestlib模塊)時(shí),程序編譯時(shí)會鏈接該庫。最終的程序執(zhí)行時(shí)也不會出現(xiàn)控制臺。
如果我們指定了 CONFIG+= console (或者使用了 qtestlib模塊)時(shí),程序鏈接時(shí)將不需要該庫,程序運(yùn)行時(shí)也會出現(xiàn)控制臺。
那么?這個(gè) qtmain 庫內(nèi)到底是什么東西呢,會不會和WinMain有什么瓜葛?
如果找到源碼就好辦了,恩 %QTDIR%\src\winmain\qtmain_win.cpp
打開一看,一切明白了:
- /*
- WinMain() - Initializes Windows and calls user's startup function main().
- NOTE: WinMain() won't be called if the application was linked as a "console" application.
- */
- #ifdef Q_OS_WINCEint WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR
- /*wCmdParam*/,
- int cmdShow)#elseextern "C"int APIENTRY WinMain(HINSTANCE instance,
- HINSTANCE prevInstance, LPSTR
- /*cmdParamarg*/, int cmdShow)#endif{...}
原來WinMain在這兒藏著呢。當(dāng)我們創(chuàng)建不帶控制臺的程序時(shí),Qt將鏈接qtmain這么庫,這個(gè)庫封裝了WinMain。最終我們自己的main函數(shù)在這個(gè)WinMain中被調(diào)用了。
這么做的好處? 我想最主要的一點(diǎn)或許是:
把各種平臺下的入口函數(shù)封裝起來,易于編譯跨平臺的程序(至少不用我們用預(yù)處理宏來寫各種入口函數(shù)了)
入口函數(shù)與嵌入可執(zhí)行文件的啟動函數(shù)
main
- mainCRTStartup
- inMain
- WinMainCRTStartup
MSVC
對 MSVC 系列的編譯器,指定鏈接子系統(tǒng)比如 /subsystem:console,鏈接器就會尋找main函數(shù),并選擇mainCRTStartup函數(shù);對windows子系統(tǒng),情況類似。
當(dāng)我們程序的入口函數(shù)是 WinMain 時(shí),如果指定 console 子系統(tǒng),鏈接器將報(bào)錯(cuò),這時(shí)我們可以指定入口點(diǎn)啟動函數(shù) /entry:WinMainCRTStartup 來解決這種問題。
Mingw
Mingw 的情況與 MSVC系列有所不同,據(jù)說是下面這個(gè)樣子:
Mingw運(yùn)行時(shí)提供了兩個(gè)入口點(diǎn)啟動函數(shù):
mainCRTStartup() 對控制臺程序 (-subsystem,console)
WinMainCRTStartup() 對GUI程序 (-subsystem,windows)
但這兩個(gè)函數(shù)都調(diào)用的是:
__mingw_CRTStartup()這樣一來,控制臺程序和GUI程序的行為時(shí)一樣的:
調(diào)用 main 函數(shù)
如果 main 函數(shù)不存在,libmaingw32.a將被鏈接進(jìn)來,該庫里面提供了一個(gè)main函數(shù)(該函數(shù)將調(diào)用用戶的WinMain函數(shù))
小結(jié):解析 Qt 在 Windows 下入口函數(shù)實(shí)現(xiàn)實(shí)例的內(nèi)容介紹完了,希望本文對你有所幫助。