C++對dll連結庫的顯示(動態)呼叫和隱式(靜態)呼叫
C++呼叫dll連結庫的方式有兩種:動態呼叫(又叫顯示呼叫)、靜態呼叫(又叫隱式呼叫)。
一、靜態呼叫dll
靜態呼叫,又稱隱式呼叫。由編譯系統完成對DLL的載入和應用程式結束時DLL解除安裝的編碼,Windows作業系統會負責控制DLL匯入記憶體的次數。這種呼叫方式簡單,能夠滿足通常的要求。通常採用的方法是把產生動態連線庫時產生的.LIB檔案(函式入口位置檔案)加入到應用程式的工程中,想使用DLL中的函式時,只須在原始檔中宣告一下。
LIB檔案包含了每一個DLL匯出函式的符號名和可選擇的標識號以及DLL檔名,不含有實際的程式碼。Lib檔案包含的資訊進入到生成的應用程式中,被呼叫的DLL檔案會在應用程式載入時同時載入在到記憶體中。
具體方法:
1、在使用連結庫的程式碼開頭加入,第二行是要呼叫的連結庫裡的函式:
#pragma comment(lib,"mydll.lib")
extern "C" __declspec(dllimport) int hello(int);
2、將要呼叫的連結庫的lib放入專案原始碼中,然後編譯。(編譯的時候不需要dll。這裡把靜態部分lib編譯進了exe,但動態庫dll還沒用。)
3、執行之前要把dll放到exe目錄下。
二、動態呼叫dll
動態呼叫,即顯式呼叫,是由程式設計者用API函式載入和解除安裝DLL來達到呼叫DLL的目的,比較複雜,但能更加有效地使用記憶體。在Windows系統中,與動態庫呼叫有關的函式包括:
①LoadLibrary(或MFC 的AfxLoadLibrary),裝載動態庫。
②GetProcAddress,獲取要引入的函式,將符號名或標識號轉換為DLL內部地址。
③FreeLibrary(或MFC的AfxFreeLibrary),釋放動態連結庫。
具體方法:
1.宣告標頭檔案<windows.h>。
2.然後用typedef定義一個指標函式型別,typedef int(*fun)(int) 。這個指標型別,要和你呼叫的函式型別和引數保持一致。
3.定義一個控制代碼例項,用來取DLL的例項地址。HINSTANCE hdll。格式為hdll=LoadLibrary(“DLL地址”);這裡字串型別是LPSTR,當是unicode字符集的時候會不行,因此要在配置-屬性-常規裡面把預設字符集“unicode”改成支援多字元擴充套件即可。4.取的地址要判斷,返回的控制代碼是否為空,如果為無效控制代碼,那麼要釋放載入DLL所佔用的記憶體。
6.然後通過函式指標來呼叫函式。FUN(int count);這裡不能用函式名來使用函式,因為這個DLL本身不是當前CPP的一部分,而是通過windows去呼叫.沒有在這個工程裡宣告或者定義,而是暴露出一個頭,要指標獲取他的地址,通過指標來呼叫。
程式碼:
#include <stdio.h>
#include <Windows.h>
typedef int(*dllfun)(int); //定義形式對應的函式指標型別
int main()
{
int a = 2;
dllfun lucky; //宣告一個函式指標
HINSTANCE hdll;
hdll = LoadLibrary("mydll.dll");
if(hdll == NULL)
{
printf("無法載入dll\n");
FreeLibrary(hdll);
getchar();
return 0;
}
lucky = (dllfun)GetProcAddress(hdll,"lucky");
if(lucky == NULL)
{
printf("無法獲取函式地址\n");
FreeLibrary(hdll);
getchar();
return 0;
}
int b = lucky(a);
printf("%d\n",b);
FreeLibrary(hdll);
getchar();
return 1;
}