其中,這些函數何去何來,這個就是我們要弄清楚的祕密。
- MFC42D.DLL
- MSVCRTD.DLL
- MFCO42D.DLL
- OLEAUT32.DLL
2.MFC的組成
直接揭開謎底:MFC由四部分組成。可能這種說法不準確,應該說,VC的核心底層API由下面部分組成:
- CRT(C runtime): 最底層的微軟對c、c++標準庫的實現版本;接口參照標準規範;MFC依賴於此。但是windows API不依賴於此,有內部自己的實現版本。
- Windows API: 微軟的操作系統怎麼弄出來的,全靠它們了,以C的API形式提供。
- MFC: 對windows API進行類的封裝。基本上涵蓋部分CRT和全部Windows API。該小組是AFX小組。
- ATL: 微軟全面邁入組件解決方案時的封裝。該小組是Com小組。
如下表:
其實看看vc的目錄組織結構大概也知道其分組。
MFC 靜態庫和動態庫
最流行的是使用MFC作爲dll,同時將自身的也作爲dll。在這種情況下,如果深挖進去,最容易發現的是MFC的dll。
參照 MSDN中的“Naming Conventions for MFC DLLs”,可以發現,基於動態鏈接庫的MFC的命名規範爲:MFC[D|O|N]x[U][D].DLL。
主要包含的屬性爲:功能模塊(Core | OLE | DB | NET),版本(VC6對應42,VS2003對應70,VS2005對應80,VS2008對應90),是unicode還是Ansi,是release還是debug。
稍微注意的是:debug版本下每個功能模塊對應一個lib;但是release版本下,合起來爲一個統一的lib文件MFC42.lib。
其實還存在,靜態鏈接庫。但是其名字可能更不着調 :[N|U]AFXDW[D].LIB
其中包含unicode和非unicode,debug和release區分。
CRT 靜態庫和動態庫
參照MSDN中的“INFO: What Are the C/C++ Libraries My Program Would Link With?”。
當我們調用sprintf,wcslen等此類函數時,我們就依賴了該庫。
這個可以通過編譯設置:
實際上對應的編譯項是:/MD /ML /MT
3.靜態庫和動態庫
核心
有關靜態庫和動態庫的相關概念,以及連接中出現的一些問題,其實所有的核心就是:
- 搞清楚引用別人的庫是靜態還是動態庫;
- 把自己作爲庫給別人使用時是靜態庫還是動態庫
真正所謂取之與民,用之於民。
其中還經常出現的一個問題是,引用的系統底層庫有哪些,到底是靜態庫還是動態庫。通常,對於MFC程序,一定會依賴於MFC庫;可以選擇性的依賴CRT庫。搞清楚使用的靜態庫和動態庫,不要衝突就行。
幾種靜態庫和動態庫
在VC6中,對於靜態動態庫,去除組件作爲一種特殊的動態庫外,還剩下5種類型。一一生成一個演示程序,研究設置,大概就可以看出區別。
靜態庫導出的是 h頭文件和lib文件。該lib文件包含着程序代碼,會比較大。源代碼編譯的時候使用頭文件,鏈接的時候使用lib文件,運行時就不需要庫文件了。
動態庫導出的是 h頭文件、lib和dll文件。該lib文件只包含着程序的函數索引位置,比較小。源代碼編譯時使用頭文件,鏈接時使用lib文件,運行時需要dll文件。
這是MFC dll
以下是對各dll分析:
其實,本質上可以看出,只有兩種庫:靜態庫和動態庫;標明自身是靜態庫還是動態庫。
靜態庫由於生來是被別人使用的,所以也就不存在導入導出標識;
而動態庫一定要存在導入導出標識。對於dll,存在MFC dll和普通的win dll。其實所謂的MFC dll只不過是將DllMain進行特殊封裝,特別是爲了方便資源的存取。而所謂的Extension dll,只不過是爲了兼容C;要求只導出非MFC類的函數而已。
這些靜態庫如何使用MFC 庫,如何使用CRT庫,其實都是可以設置的。這點用來解決引用庫是什麼庫。
對於靜態庫和動態庫,MFC嚮導生成時,會自動弄出一些編譯設置項。但是最根本的核心還是dsp中的:
# TARGTYPE "Win32 (x86) Static Library" 0x0104
!MESSAGE "TestStaticLib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "TestStaticLib - Win32 Debug" (based on "Win32 (x86) Static Library")
如果要將一個靜態庫編譯成另一個動態庫,或者相反;只需要在dsp中統一查找替換爲另一種格式即可。當然,更加鼓勵的是生成多個編譯配置項。