簡體   English   中英

為什么我們需要在 Windows C++ 中鏈接 kernel32.dll、user32.dll 等...?

[英]Why do we need to link kernel32.dll, user32.dll, etc… in Windows C++?

為什么 Visual Studio 默認包含 kernel32.dll、user32、dll、winspool.lib 等的附加依賴項...?

為什么這些資源需要鏈接到 Windows 上的 C++ 項目中,它們實際上是變成了機器代碼並直接插入到每個可執行文件中,還是與可執行文件分開並在運行時在它們之間建立鏈接?

為了讓 C++ 應用程序在 windows 下運行,它至少需要一些系統服務。 例如,它需要分配和釋放內存,需要獲取調用它的命令行參數,完成后需要能夠退出操作系統。 通常,它也需要以某種方式接收輸入並產生輸出,無論是通過 GUI,還是通過控制台,或者通過網絡,或者只是通過在文件系統上讀寫文件。

這些服務都不是魔法提供的; 它們中的每一個都由 kernel32.dll、user32.dll 等提供。

這種功能是由 C 和 C++ 的標准庫提供的,這是一種常見的誤解。 那不是真的,因為如果是這樣,那么這些庫將能夠施展魔法。 標准庫提供的服務是通過委托給主機系統的本地服務來實現的。

因此,當您調用malloc() ,Windows 的標准 C/C++ 庫將在內部調用GlobalAlloc() (在 Kernel32.dll 中實現),而 MacOS 的標准 C/C++ 庫將在內部調用vm_allocate()或類似的東西。 理解這一點非常重要:對於每個不同的主機系統,存在標准庫的不同實現,它利用該主機系統的本機服務。

標准庫的好處在於它們建立了一個眾所周知的公共接口,您的 C/C++ 代碼可以期望擁有該接口,這樣您的 C/C++ 代碼就不必知道,也不必擔心,確切地說它在什么主機系統中運行。

在 Windows 下,您的程序不會與 DLL 完全鏈接,因為鏈接是創建可執行文件的過程,而 DLL 僅在運行時起作用。 您的程序與庫相關聯,因此對於每個 DLL,通常都有一個相應的 LIB。 例如,對於 Kernel32.DLL,有 Kernel32.LIB,因此您的程序將與 Kernel32.LIB 鏈接。

這些 LIB 很小,因為它們不包含實際代碼。 當你的程序運行時 Kernel32.LIB 所做的是它要求相應的 Kernel32.DLL 存在,它要求操作系統加載 Kernel32.DLL,(要求它更可能映射到你的進程的內存空間,因為 Kernel32.DLL 通常已經被加載,) 然后它將每個庫調用重定向到 DLL 的相應入口點。

所以,是的,每個 C++ 程序都需要使用這些 DLL,不,它並沒有完全鏈接 DLL 本身,它只鏈接相應的 LIB,然后將調用委托給 DLL,而 LIB 很小,所以不要不要擔心他們。

請注意,理論上可以編寫一個自包含的程序,不需要任何這些 DLL,但這樣的程序幾乎不能做任何事情:一旦加載,它將被限制為除了獨立思考,無法接受任何輸入,也無法產生任何輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM