使用動態DLL有兩種方法,一種是隱式鏈接,一種是顯式鏈接,如果用loadlibrary就是顯示鏈接,用lib就屬於隱式鏈接。
兩種方法對於你的程序調用動態庫時沒有任何區別,只是你在編程時,步驟是不一樣的。顯式調用麻煩了點,但可以沒有相應的lib庫;隱式調用,使用起來比較簡單,有函數的聲明就可以了,但必須有lib庫。
隱式加載默認是加載到內存中的,始終占用內存。
顯示加載,你加載時占用內存,釋放了就不占用內存了。如果該DLL已經載入,loadlibrary只是會增加一個引用計數,相同,freelibrary也只是減少引用計數,如果引用計數為0時,DLL才從內存中移除。
顯式和隱式只是對於代碼編寫時來說的,最后產生的可執行程序,不管是顯式和隱式,都是用loadlibrary載入的。顯式與隱式不是用在這些方面的,顯式加載適合需要動態的選 用DLL的情況。
在VC中兩種方式的具體方法: 一、動態庫的隱示調用: 在 VC 工程中直接鏈接靜態輸入庫XXX.lib,然后即可像調用其它源文件中 的函數一樣調用DLL中的函數了。 二、動態庫的顯式調用: 顯式調用動態庫步驟: 1、創建一個函數指針,其指針數據類型要與調用的 DLL 引出函數相吻 合。 2、通過 Win32 API 函數LoadLibrary()顯式的調用DLL,此函數返回 DLL 的實例句柄。 3、通過 Win32 API 函數GetProcAddress()獲取要調用的DLL 的函數地 址,把結果賦給自定義函數的指針類型。 4、使用函數指針來調用 DLL 函數。 5、最后調用完成后,通過 Win32 API 函數FreeLibrary()釋放DLL 函數。
動態鏈接庫的加載方式: 1)隱式鏈接 使用lib引入庫和相關頭文件,dll文件配合使用。 2)顯示加載 只是使用dll文件即可。 顯示加載的使用方法:
void CDlltextDlg::OnAdd() { // TODO: Add your control notification handler code here HINSTANCE hnst=LoadLibrary("dll2");//得到動態鏈接庫的句柄 typedef int (*ADDPROC)(int a,int b);//定義函數指針類型 //用函數指針變量來調用函數 int *add(int a,int b)表示函數返回指針值 ADDPROC Add=(ADDPROC)GetProcAddress(hnst,"add");//得到動態鏈接庫中add導出函數的地址 if(!Add) { MessageBox("獲得函數地址失敗!"); return; } CString str; str.Format("5+3=%d",Add(5,3)); MessageBox(str); FreeLibrary(hnst);//釋放動態鏈接庫 }
GetProcAddress也可以采用函數序號的方式來進行調用,不過最好是用函數名來獲取函數地址。 ADDPROC Add=(ADDPROC)GetProcAddress(hnst,MAKEINTRESOURCE(1) );
//得到動態鏈接庫中add導出函數的地址,第1個函數表示為add函數 FreeLibrary減少加載動態鏈接庫的引用計數,當引用計數為0的時候,該模塊將從調用進程的地址空間中被卸載。句柄不再有效。 動態鏈接庫的好處:在需要的時候加載動態鏈接庫某個函數。 隱式鏈接的缺點:使用比較簡單,在程序的其他部分可以任意使用函數,但是當程序訪問十來個dll動態鏈接庫的時候,此時如果都使用隱式鏈接的時候,啟動此程序的時候,這十來個動態鏈接庫都需要加載到內存,映射到內存的地址空間,這就會加大進程的啟動時間,而且程序運行過程中,只是在某個條件下使用某個函數,如果使用隱式鏈接會造成資源的浪費。這樣需要采用動態加載的方式。