標籤:
個人建議:能使用靜態庫的就不要使用動態庫,能使用隱式調用的就不要用顯示調用。
注意:
(1)動態庫中的.lib檔案叫做匯入庫,對於匯入庫而言,其實際的執行代碼位於動態庫中,匯入庫只包含了地址符號表等,確保程式找到對應函數的一些基本地址資訊。
靜態庫中的.lib叫做靜態庫,本身就包含了實際執行代碼、符號表等等
(2)顯示調用一定要用extern “C” 變為C標準編譯,可杜絕C++的重載
靜態庫:在連結階段將彙編產生的目標檔案.o與引用庫一起連結打包到可執行檔中,可簡單看成(.o或者.obj檔案的集合)。(1)對函數庫的連結是放在編譯時間期完成的(2)程式在運行時與函數庫沒有瓜葛,移植方便(3)浪費空間和資源
靜態庫的建立:建立Win32項目-》Lib-》添加C++類-》添加函數
static double add(double a,double b);
調用:(1)若為第三方庫-》VC++目錄-》包含目錄,庫目錄
連結器-》輸入-》附加依賴項
(2)若在同一個工程中-》通用屬性-》架構和引用-》添加新引用
動態庫:
(1)將庫函數的連結載入延遲到程式運行時期
(2)可以實現進程間的資源共用(因此也稱為共用庫)
(3)將一些程式升級變得簡單
(4)可以真正的做到連結載入完全由程式員在程式碼中控制(顯示調用)
動態庫的建立:(1)和靜態庫一樣,然後屬性-》配置屬性-》常規-》配置類型
(2)win32工程-》dll
Windows系統下的執行檔案格式是PE格式,動態庫需要一個DllMain函數做初始化入口,通常用__declspecl(dllexport)關鍵字
static __declspec(dllexport) double add(double a,double b);
調用:
(1)若為第三方庫-》VC++目錄-》包含目錄,庫目錄
連結器-》輸入-》附加依賴項lib
dll考入到當前工作目錄下
(2)若在同一個工程中-》通用屬性-》架構和引用-》添加新引用
(3)顯示調用若非類中函數-》VC++目錄-》包含目錄.h
.cpp中添加標頭檔typedef double (*Add)(double,double)函數申明
HINSTANCE stance = LoadLibraryA("../../Dll/StaticClassDll.dll")動態載入dll
Add add = (Add)GetProcAddress(stance,"AddDllGlobal")擷取函數
double c = add(10,10)使用函數
FreeLibrary(stance)釋放控制代碼
(4)顯示調用若為類函數涉及到重載,則需要通過dll分析器進行名字粉碎從而和(3)中相同調用即可
AddM addm = (AddM)GetProcAddress(stance,"[email protected]@@[email protected]");
example:
動態:
#ifdef XIANSHIDLL_EXPORTS
#define XIANSHIDLL_API __declspec(dllexport) //為了書寫方便
#else
#define XIANSHIDLL_API __declspec(dllimport)
#endif
// 此類是從 XIANSHIDll.dll 匯出的
extern "C" class XIANSHIDLL_API CXIANSHIDll { //extern "C" 為了可顯示調用類中函數
public:
CXIANSHIDll(void);
double AddXian(double a,double b); //類中函數涉及重載需要進行函數粉碎,用dll分析器即可得到
};
extern XIANSHIDLL_API int nXIANSHIDll; //匯出變數的介面
XIANSHIDLL_API int fnXIANSHIDll(void); //類外函數可直接進行顯示調用
Windows靜態庫和動態庫區別