DLL函式封裝及呼叫例項
阿新 • • 發佈:2019-02-06
動態呼叫的意思是顯式呼叫,是由使用者自己選擇呼叫哪個DLL檔案,在windows系統中,與動態連結庫呼叫相關的函式主要有3個:
1.LoadLibrary,顧名思義,該函式的作用是載入DLL檔案,因此該函式的引數就是你想要使用的DLL檔案;
2.GetProcAddress,大概意思是獲得欲使用函式的地址,其有兩個引數,一個是後面會提到的控制代碼,另外一個就是DLL中的函式;
3.FreeLibrary,釋放動態連結庫。
下面通過一個例項來演示如何定義並顯式呼叫DLL中的函式。
建立生成自己的dll檔案
簡單起見,我們dll中只包含一個函式,這個函式我們起名叫做multiply,作用就是實現兩個數的相乘。我們新建一個專案multiplydll如下圖點選確定,下一步,選擇DLL,完成,如下圖
得到如下圖所示結果,注意在原始檔部分會自動生成multiplydll.cpp檔案,我們將在裡面新增我們的乘函式
新增乘函式,編譯成功如下圖
此時我們去專案目錄下F:\src\multiplydll\Debug會看到一個生成的dll檔案如下:
測試呼叫我們生成的DLL檔案中的函式
現在我們新建立一個專案,來測試呼叫我們生成的dll。我們新建一個專案multi_test,確定,下一步,空專案,見下面兩圖新增原始檔test做簡單的測試
簡單起見,我們將生成的dll檔案複製到當前專案下,如下圖
注意在新建的測試專案中需要做一點更改如下圖
測試程式碼如下:
結果#include<iostream> #include<Windows.h>//這個標頭檔案非常重要,必須加上! using namespace std; typedef int(*dllfunc)(int a, int b);//這裡的dllfun形式上和我們生成的DLL檔案中的函式一致,我們的dll中定義的函式有兩個整型引數,因此這裡也是int a,int b int main() { HINSTANCE hdll;//定義一個控制代碼例項,來獲取dll的例項地址 //這裡為簡單起見,我們直接將生成的multiply.dll檔案複製到當前專案下,否則下面一句你需要替換成dll的地址 hdll = LoadLibrary("multiplydll.dll");//載入生成的dll檔案,因為我們把生成的dll檔案複製到當前專案目錄下了,所以直接寫就行了 //下面判斷當前dll是否載入成功 if (hdll == NULL) { cout << "DLL載入失敗" << endl; return 0; } //如果通過上面則表明載入成功了,下面我們需要取出dll裡面函式的地址 dllfunc add_obj = (dllfunc)GetProcAddress(hdll, "multiply");//此處兩個引數一個是我們的控制代碼,另外一個是dll中函式名,取出來給add_obj //同樣,取址是否成功呢?判斷一下! if (add_obj == NULL) { cout << "獲取DLL中函式地址失敗!" << endl; return 0; } //獲取函式地址成功後,我們就可以使用dll中的函數了 cout << add_obj(3, 5) << endl; FreeLibrary(hdll); return 0; }
注意:上面的DLL中僅僅包含一個函式,那如果我想實現多個函式的封裝呼叫該怎麼辦呢?一個可行但麻煩的方法是對每一個函式單獨建一個dll,然後分別載入每個dll再呼叫每個函式,顯然這是非常麻煩的。這個“問題”也困擾了我兩天,但是突然注意到,在載入完dll之後我們獲取的是dll函式中的地址啊!引數是函式名而不是dll的名字!因此,只需要一個dll就可以。其餘步驟類似,下面給出一個求面積的例項,分別求矩形面積和圓形面積,程式碼及執行結果如下:
#include<iostream>
#include<Windows.h>
using namespace std;
typedef double(*dllfun1)(double l, double d);
typedef double(*dllfun2)(double r);
int main()
{
double width, length;
cout << "please enter the width and length of a rectangle:" << endl;
cin >> width >> length;
HINSTANCE hdll;
hdll = LoadLibrary("myArea.dll");
if (hdll == NULL)
{
cout << "DLL載入失敗" << endl;
return 0;
}
dllfun1 re = (dllfun1)GetProcAddress(hdll, "rect");
if (re == NULL)
{
cout << "獲取DLL函式地址失敗" << endl;
return 0;
}
cout << "Area of the rectangle is:" << re(length, width) << endl;
double radius;
cout << "please enter the radius of a circle:" << endl;
cin >> radius;
dllfun2 ci = (dllfun2)GetProcAddress(hdll, "circle");
if (ci == NULL)
{
cout << "獲取DLL函式地址失敗" << endl;
return 0;
}
cout << "Area of the circle is:" << ci(radius) << endl;
FreeLibrary(hdll);
return 0;
}
參考:http://blog.csdn.net/very_2/article/details/6534915 http://blog.csdn.net/ojshilu/article/details/12954957