在C++中调用DLL中的函数(2)
本文轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_53004b4901009h3b.html
?
應(yīng)用程序使用DLL可以采用兩種方式:
一種是隱式鏈接,另一種是顯式鏈接。在使用DLL之前首先要知道DLL中函數(shù)的結(jié)構(gòu)信息。
Visual C++6.0在VC\bin目錄下提供了一個(gè)名為Dumpbin.exe的小程序,用它可以查看DLL文件中的函數(shù)結(jié)構(gòu)。另外,Windows系統(tǒng)將遵循下面的搜索順序來定位DLL:
1.包含EXE文件的目錄,
2.進(jìn)程的當(dāng)前工作目錄,
3.Windows系統(tǒng)目錄,
4.Windows目錄,
5.列在Path環(huán)境變量中的一系列目錄。
1.隱式鏈接
隱式鏈接就是在程序開始執(zhí)行時(shí)就將DLL文件加載到應(yīng)用程序當(dāng)中。實(shí)現(xiàn)隱式鏈接很容易,只要將導(dǎo)入函數(shù)關(guān)鍵字_declspec(dllimport)函數(shù)名等寫到應(yīng)用程序相應(yīng)的頭文件中就可以了。
隱式鏈接采用靜態(tài)加載的方式,比較簡單,需要.h、.lib、.dll三件套。新建“控制臺(tái)應(yīng)用程序”或“空項(xiàng)目”。配置如下:項(xiàng)目->屬性->配置屬性->VC++ 目錄-> 在“包含目錄”里添加頭文件Mydll.h所在的目錄?
項(xiàng)目->屬性->配置屬性->VC++ 目錄-> 在“庫目錄”里添加頭文件Mydll.lib所在的目錄?
項(xiàng)目->屬性->配置屬性->鏈接器->輸入-> 在“附加依賴項(xiàng)”里添加“Mydll.lib”(若有多個(gè) lib 則以空格隔開)
下面的例子通過隱式鏈接調(diào)用MyDll.dll庫中的Min函數(shù)。首先生成一個(gè)項(xiàng)目為testDLL,在testDLL.h、testDLL.cpp文件中分別輸入如下代碼:
?//testDLL.h
#pragma?comment(lib,"MyDll.lib")extern?"C"_declspec(dllimport)?int?Max(int?a,int?b);
extern?"C"_declspec(dllimport)?int?Min(int?a,int?b);
//TestDll.cpp
#include
#include"Dlltest.h"
void?main()
{int?a;
a=min(8,10)
printf("比較的結(jié)果為%d\n",a);
}
?在創(chuàng)建DllTest.exe文件之前,要先將MyDLL.dll和MyDLL.lib拷貝到當(dāng)前工程可執(zhí)行文件所在的目錄下面(非常重要),也可以拷貝到windows的System目錄下。如果DLL使用的是def文件,要?jiǎng)h除testDLL.h文件中關(guān)鍵字extern "C"。testDLL.h文件中的關(guān)鍵字Progam commit是要Visual C+的編譯器在link時(shí),鏈接到MyDll.lib文件,當(dāng)然,開發(fā)人員也可以不使用#pragma comment(lib,"MyDLL.lib")語句,而直接在工程的Setting->Link頁的Object/Moduls欄填入MyDll.lib既可。
2.顯式鏈接
顯式鏈接是應(yīng)用程序在執(zhí)行過程中隨時(shí)可以加載DLL文件,也可以隨時(shí)卸載DLL文件,這是隱式鏈接所無法作到的,所以顯式鏈接具有更好的靈活性,對(duì)于解釋性語言更為合適。不過實(shí)現(xiàn)顯式鏈接要麻煩一些。在應(yīng)用程序中用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將自己所做的動(dòng)態(tài)鏈接庫調(diào)進(jìn)來,動(dòng)態(tài)鏈接庫的文件名即是上述兩個(gè)函數(shù)的參數(shù),此后再用GetProcAddress()獲取想要引入的函數(shù)。自此,你就可以象使用如同在應(yīng)用程序自定義的函數(shù)一樣來調(diào)用此引入函數(shù)了。在應(yīng)用程序退出之前,應(yīng)該用FreeLibrary或MFC提供的AfxFreeLibrary釋放動(dòng)態(tài)鏈接庫。下面是通過顯式鏈接調(diào)用DLL中的Max函數(shù)的例子。?#include
#includevoid?main(void)
{
typedef?int(*pMax)(int?a,int?b);
typedef?int(*pMin)(int?a,int?b);
HINSTANCE?hDLL;
PMax?Max
HDLL=LoadLibrary("MyDll.dll");//加載動(dòng)態(tài)鏈接庫MyDll.dll文件;
Max=(pMax)GetProcAddress(hDLL,"Max");
A=Max(5,8);
Printf("比較的結(jié)果為%d\n",a);
FreeLibrary(hDLL);//卸載MyDll.dll文件;
}
?
?
?
在上例中使用類型定義關(guān)鍵字typedef,定義指向和DLL中相同的函數(shù)原型指針,然后通過LoadLibray()將DLL加載到當(dāng)前的應(yīng)用程序中并返回當(dāng)前DLL文件的句柄,然后通過GetProcAddress()函數(shù)獲取導(dǎo)入到應(yīng)用程序中的函數(shù)指針,函數(shù)調(diào)用完畢后,使用FreeLibrary()卸載DLL文件。在編譯程序之前,首先要將DLL文件拷貝到工程所在的目錄或Windows系統(tǒng)目錄下。
?
使用顯式鏈接應(yīng)用程序編譯時(shí)不需要使用相應(yīng)的Lib文件。另外,使用GetProcAddress()函數(shù)時(shí),可以利用MAKEINTRESOURCE()函數(shù)直接使用DLL中函數(shù)出現(xiàn)的順序號(hào),如將GetProcAddress(hDLL,"Min")改為GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函數(shù)Min()在DLL中的順序號(hào)是2),這樣調(diào)用DLL中的函數(shù)速度很快,但是要記住函數(shù)的使用序號(hào),否則會(huì)發(fā)生錯(cuò)誤。?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的在C++中调用DLL中的函数(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在QT中配置snap7库
- 下一篇: 微信开通检测软件的原理及使用方法