2 回答

TA貢獻22條經驗 獲得超11個贊
這個問題不是一兩句話可以解釋完
1、微軟提供給我們的MFC已經編譯成靜態LIB和動態LIB,同時,為方便調試,微軟將MFC源碼(CPP文件)也放到VC里一起發布了;這里會存在兩種情況,如果是靜態LIB,那么功能代碼會在鏈接時鏈接進你的EXE文件中,所以這種靜態LIB方式時,EXE文件通常都比較大;如果是動態LIB的方式,那么運行的時候就需要mfcxxx.dll文件,但EXE文件體積比較小
2、如果你理解了1,我再進一步解釋,MFC工程配置的時候默認會鏈接mfcxxx.lib的,所以你的工程里只需要包含對應的頭文件,例如 afxxxx.h之類的文件即可,編譯器在編譯階段是不需要知道具體實現代碼在哪里的,它只需要知道聲明即可編譯通過,同時編譯器會將那些外部的函數(即不是在當前CPP文件實現的函數)標記為需要修復的(我們先把它叫做修復吧);那么,假如我用了一個MFC的函數,現在我只有聲明,它是怎么找到具體的實現代碼呢,這就是鏈接器的工作了,剛才我說過,MFC工程默認是會鏈接mfcxxx.lib的,所以鏈接器在工作的時候,它會遍歷所有編譯過的文件,從里面找出要修復的項,然后再遍歷LIB文件,如果在LIB文件里找到對應的實現,那么鏈接器會把編譯階段留下的手尾FIX掉
3、如果你理解了2,我們再進一步解釋2;鏈接器鏈接LIB的時候,會有兩種情況,第一種,這個LIB本身是一個靜態LIB,包含了具體的實現;第二種,這個LIB本身只是一個中介,它是指向DLL的某個函數的;對于第一種情況,鏈接器會把用到的所有代碼鏈接進去,注意,在Release版本情況下,鏈接器只會把用的的函數鏈進去,就是說,即使你的靜態LIB有10MB,你也不需要擔心編譯出來的EXE有10MB,它只會把用到的函數鏈進去;;對于第二種,是指向DLL某個函數的,鏈接器會在EXE的PE部里的導入表部分,增加一個項,這個項指向DLL的函數,同時在修復編譯階段留下手尾的地方,讓它JMP(跳轉)或CALL(調用)到我們DLL函數里
以上純屬個人解釋,因為在編譯鏈接階段是非常復雜的,一時間沒辦法完全解決齊,有問題可以繼續追問
- 2 回答
- 3 關注
- 1495 瀏覽
添加回答
舉報