首先來說說呼叫的原理:
呼叫dll,首先需要將dll檔案映像到使用者程序的位址空間中,然後才能進行函式呼叫,這個函式和程序內部一般函式的呼叫方法相同。windows提供了兩種將dll映像到程序位址空間的方法:隱式呼叫(通過lib和標頭檔案)和顯式呼叫(只通過提供的dll檔案)。下面對這兩種方式在vc中如何呼叫做詳細的說明:
a.隱式:
這種方法需要dll工程經編譯產生的lib檔案,此檔案中包含了dll允許應用程式呼叫的所有函式的列表,當鏈結器發現應用程式呼叫了lib檔案列出的某個函式,就會在應用程式的可執行檔案的檔案映像中加入一些資訊,這些資訊指出了包含這個函式的dll檔案的名字。當這個應用程式執行時,也就是它的可執行檔案被作業系統產生映像檔案時,系統會檢視這個映像檔案中關於dll的資訊,然後將這個dll檔案映像到程序的位址空間。
·程式執行時的目錄,即可執行檔案所在的目錄;
·當前程式工作目錄
·系統目錄:對於windows95/98來說,可以呼叫getsystemdirectory函式來得到,對於windowsnt/2000來說,指的是32位windows的系統目錄,也可以呼叫getsystemdirectory函式來得到,得到的值為system32。
·windows目錄
·列在path環境變數中的所有目錄
vc中載入dll的lib檔案的方法有以下三種:
①lib檔案直接加入到工程檔案列表中
在vc中開啟file view一頁,選中工程名,單擊滑鼠右鍵,然後選中「add files to project」選單,在彈出的檔案對話方塊中選中要加入dll的lib檔案即可。
②設定工程的 project settings來載入dll的lib檔案
開啟工程的 project settings選單,選中link,然後在object/library modules下的文字框中輸入dll的lib檔案。
③通過程式**的方式
加入預編譯指令#pragma comment (lib,」*.lib」),這種方法優點是可以利用條件預編譯指令鏈結不同版本的lib檔案。因為,在debug方式下,產生的lib檔案是debug版本,如regd.lib;在release方式下,產生的lib檔案是release版本,如regr.lib。
當應用程式對dll的lib檔案載入後,還需要把dll對應的標頭檔案(*.h)包含到其中,在這個標頭檔案中給出了dll中定義的函式原型,然後宣告。
b.顯式
隱式鏈結雖然實現較簡單,但除了必須的*.dll檔案外還需要dll的*.h檔案和*.lib檔案,在那些只提供*.dll檔案的場合就無法使用,而只能採用顯式鏈結的方式。這種方式通過呼叫api函式來完成對dll的載入與解除安裝,其能更加有效地使用記憶體,在編寫大型應用程式時往往採用此方式。這種方法程式設計具體實現步驟如下:
①使用windows api函式load library或者mfc提供的afxloadlibrary將dll模組映像到程序的記憶體空間,對dll模組進行動態載入。
②使用getprocaddress函式得到要呼叫dll中的函式的指標。
③不用dll時,用free library函式或者afxfreelibrary函式從程序的位址空間顯式解除安裝dll
vc中呼叫例項
資料加密是計算機安全領域的重要內容,其基本思想是通過變換資訊的表現形式來保護敏感資訊,使非授權者不能了解被保護資訊的內容[4]。常見的資料加密演算法有:des,idea,rsa,ecc,aes,md5,sha等。
《共享軟體加密演算法庫》是一款針對個人、企業開發共享軟體的加密工具,支援windows平台下各類開發工具:vc、vb、delphi、pb、vfp 等,演算法庫整合的演算法有:blowfish、md5、secret16、aes、sha、crc32、rsa、des、字串加/解密、檔案加/解密等多種功能強大的演算法。其提供了dll檔案—reg.dll,可以通過復用它來實現資料加密與解密。
隱式鏈結
其提供了 reg.h與reg.lib兩個隱式鏈結所必須的檔案,所以可以採用此種方式。
①在vc中開啟file view一頁,選中工程名,單擊滑鼠右鍵,然後選中「add files to project」選單,在彈出的檔案對話方塊中選中要加入reg.lib。
②在vc中開啟file view一頁,選中header files,單擊滑鼠右鍵,然後選中「add files to folder」選單,在彈出的檔案對話方塊中選中要加入reg.h,然後在工程相應的標頭檔案中加入#i nclude "reg.h"。在reh.h標頭檔案中給出了dll中定義的函式原型及宣告。
如:加密函式原型及宣告為extern "c" bool winapi file encrypt(lpctstr lpinputfilename, lpctstr lpoutputfilename, lpctstr lpkey, lpctstr lpregistercode);解密函式原型及宣告為extern "c" bool winapi file decrypt(lpctstr lpinputfilename, lpctstr lpoutputfilename, lpctstr lpkey, lpctstr lpregistercode)。其中對於winapi巨集,把它加到函式原型定義前,系統會把它翻譯為適當的呼叫方式,在win32中,是把它翻譯為_stdcall呼叫方式。
③直接呼叫所需要的加密與解密函式,如呼叫file encrypt()函式實現文字檔案和二進位制檔案的加密,呼叫file decrypt()函式實現文字檔案和二進位制檔案的解密,呼叫時的引數要與函式定義引數相符合。
顯式鏈結
如果只提供reg.dll乙個檔案,那麼須用此種方式。
//裝載加密/解密dll
hinstance hdll=::load library ("reg.dll");
//通過型別定義語句typedef來定義函式指標型別
typedef bool (_stdcall *lpfileencrypt)(lpctstr, lpctstr, lpctstr, lpctstr);
//函式宣告
lpfileencrypt fileencrypt1;
//獲取加密函式file encrypt的函式指標
fileencrypt1=(lpfileencrypt)::getprocaddress(hdll,"fileencrypt");
//呼叫dll中加密函式file encrypt對檔案加密,user-12345678為軟體註冊號
fileencrypt1(加密源檔名,加密生成目標檔名,密碼,"user-12345678");
//釋放dll模組
::afxfreelibrary(hdll);
//裝載加密/解密dll
hinstance hdll=::load library ("reg.dll");
//通過型別定義語句typedef來定義函式指標型別
typedef bool (_stdcall *lpfiledecrypt)(lpctstr, lpctstr, lpctstr, lpctstr);
//函式宣告
lpfiledecrypt filedecrypt2;
//獲取解密函式file decrypt的函式指標
filedecrypt2=(lpfiledecrypt)::getprocaddress(hdll,"filedecrypt");
//呼叫dll中解密函式filedecrypt對檔案加密,user-12345678為軟體註冊號
filedecrypt2(解密源檔名,解密生成目標檔名,密碼,"user-12345678");
//釋放dll模組
::afxfreelibrary(hdll);
// file: runtime.c
// a ****** program that uses loadlibrary and
// getprocaddress to access myputs from myputs.dll. #include
typedef void (*myproc)(lptstr);
void main(void)
// free the dll module. ffreeresult = freelibrary(hinstlib); } // if unable to call the dll function, use an alternative.
if (! fruntimelinksuccess)
printf(「message via alternative method\n「);
}
呼叫靜態鏈結庫和動態鏈結庫
呼叫靜態鏈結庫 靜態鏈結庫由.h和.lib檔案組成,h檔案在工程中用來宣告,而.lib檔案包含供外界呼叫的函式的原型。vc 6.0中呼叫靜態鏈結庫.lib共3種方法 1.首先使用語句 include lib.h 並將lib.h拷貝到當前工程目錄下 接著對staticlib smp.lib使用語句 p...
呼叫動態鏈結庫(dll)
步驟 1.tools options projects and solutions vc directories分別在包含檔案,庫檔案填加了路徑 這些路徑只告訴編譯器怎麼找檔案,沒有說把那裡面的檔案加入工程.若不設定,編譯報錯 無法開啟 檔案 2.project properties c c gen...
Matlab呼叫動態鏈結庫
matlab的優勢就是矩陣計算,大量的演算法庫等,對於非矩陣計算來說可能就沒有多高的效能和優勢。matlab支援使用c語言和fortan編寫擴充套件,這樣就可以彌補matlab不擅長的部分。有些時候我們需要在matlab中呼叫已有的dll,避免寫c擴充套件。比如需要在matlab中獲取機器碼,而這個...