1.什么是DLL
DLL,即動態鏈接庫,是包含若干個函數的庫文件,可供其他程序運行時調用。
2.DLL的優缺點
優點:代碼重用,可供多個程序同時調用
缺點:易發生版本沖突
當新版本的動態鏈接庫不兼容舊版本時,其他使用該DLL的程序可能無法正常工作。
針對這一問題,我們需要在程序中加上一個manifest文件,指明該程序所使用的DLL版本號。
此時,程序將根據manifest加載指定版本的DLL,否則按默認版本加載。
3.關於LIB和DLL
LIB,是靜態鏈接庫,分為靜態lib和動態lib。
靜態lib:包含函數代碼聲明和實現,編譯后所有代碼都嵌入到宿主程序中。不需要再另行調用DLL。
動態lib:相當於一個.h頭文件,它是對實現部分(.DLL)的導出部分的聲明。編譯后宿主程序也只包括聲明部分。運行時需調用相應的DLL文件。
4.DLL編寫
1)在vs中,選擇“文件”-》“新建”-》“項目”,選擇“Visual C++”-》“win32項目”,來創建DLL類庫。
如下圖所示:
2)添加頭文件(.h)和源文件(.cpp)
mydll.h
extern "C" _declspec(dllexport) int add(int a, int b);
extern關鍵字:函數可以在本模塊或其他模塊中使用;
"C":表明函數必須按C語言方式進行編譯,因為C++支持函數的重載,編譯時會對函數名進行更改(按照函數名+參數類型),
所以需要聲明"C",以便鏈接時能正確找到相應的函數。
_declspec(dllexport)關鍵字:該函數可以從DLL中導出,程序引入DLL時,只有聲明了該關鍵字的函數,才能導入使用
mydll.cpp
#include "mydll.h" int add(int a, int b) //該DLL需要導出的函數功能:加法 { return a + b; }
編譯后,我們可以在生成目錄中找到相應的DLL文件和LIB文件。
mydll.dll,mydll.lib
5.DLL調用
調用DLL有兩種方式。
1)顯式鏈接(只使用DLL)
特點:不需要使用相應的lib文件,可隨時加載和卸載DLL,方便靈活。
void main(void) { typedef int(*padd)(int a,int b); HINSTANCE hDLL; padd add; HDLL=LoadLibrary("MyDll.dll");//加載動態鏈接庫MyDll.dll文件; add=(padd)GetProcAddress(hDLL,"add"); int result=add(5,8); Printf("計算的結果為%d\n",result); FreeLibrary(hDLL);//卸載MyDll.dll文件; }
上例通過LoadLibray()將DLL加載到當前的應用程序,並返回當前DLL文件的句柄。
然后通過GetProcAddress()函數獲取導入到應用程序中的函數指針,
函數調用完畢后,使用FreeLibrary()卸載DLL文件。
2)隱式鏈接(使用LIB,DLL)
特點:程序開始執行時將DLL文件加載到應用程序中,程序結束后,釋放DLL。
#pragma comment(lib,"MyDll.lib") extern "C"_declspec(dllimport) int add(int a,int b); void main() { int a; a=add(8,10) printf("計算的結果為%d\n",a); }
#pragma comment是預處理指令,使得鏈接器在鏈接庫的時候去找"MyDll.lib"這個庫。