中使用動態(tài)鏈接庫DLL_第1頁
中使用動態(tài)鏈接庫DLL_第2頁
中使用動態(tài)鏈接庫DLL_第3頁
中使用動態(tài)鏈接庫DLL_第4頁
中使用動態(tài)鏈接庫DLL_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、VC中使用動態(tài)鏈接庫DLL:靜態(tài)調(diào)用和動態(tài)調(diào)用2010-05-02 15:56VC中生成DLL的辦法見:-VC中使用DLL調(diào)用DLL有兩種方法:靜態(tài)調(diào)用和動態(tài)調(diào)用.(一).靜態(tài)調(diào)用其步驟如下:1.把你的youApp.DLL拷到你目標工程(需調(diào)用youApp.DLL的工程)的Debug目錄下;2.把你的youApp.lib拷到你目標工程(需調(diào)用youApp.DLL的工程)目錄下;3.把你的youApp.h(包含輸出函數(shù)的定義)拷到你目標工程(需調(diào)用youApp.DLL的工程)目錄下;4.打開你的目標工程選中工程,選擇Visual C+的Project主菜單的Settings菜單;5.執(zhí)行第4步后

2、,VC將會彈出一個對話框,在對話框的多頁顯示控件中選擇Link頁。然后在Object/library modules輸入框中輸入:youApp.lib6.選擇你的目標工程Head Files加入:youApp.h文件;7.最后在你目標工程(*.cpp,需要調(diào)用DLL中的函數(shù))中包含你的:#include youApp.h注:youApp是你DLL的工程名。(二).動態(tài)調(diào)用其程序如下:動態(tài)調(diào)用時只需做靜態(tài)調(diào)用步驟1.01 02 HINSTANCE hDllInst = LoadLibrary(youApp.DLL);03 if(hDllInst)04 05 typedef DWORD (WINA

3、PI *MYFUNC)(DWORD,DWORD);06 MYFUNC youFuntionNameAlias = NULL;07 / youFuntionNameAlias 函數(shù)別名08 youFuntionNameAlias = (MYFUNC)GetProcAddress(hDllInst,youFuntionName);09 / youFuntionName 在DLL中聲明的函數(shù)名10 if(youFuntionNameAlias)11 12 youFuntionNameAlias(param1,param2);13 14 FreeLibrary(hDllInst);15 16 顯式(靜

4、態(tài))調(diào)用:LIB + DLL + .H,注意.H中dllexport改為dllimport隱式(動態(tài))調(diào)用:DLL + 函數(shù)原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數(shù)的地址),不用后FreeLibrary-動態(tài)鏈接庫DLL的鏈接應用程序使用DLL可以采用兩種方式:一種是隱式鏈接,另一種是顯式鏈接。在使用DLL之前首先要知道DLL中函數(shù)的結構信息。Visual C+6.0在VCbin目錄下提供了一個名為Dumpbin.exe的小程序,用它可以查看DLL文件中的函數(shù)結構。另外,Windows系統(tǒng)將遵循下面的搜索順序來定位DLL: 1包含EXE文件的目錄,

5、2進程的當前工作目錄, 3Windows系統(tǒng)目錄, 4Windows目錄,5列在Path環(huán)境變量中的一系列目錄。(一).隱式鏈接隱式鏈接就是在程序開始執(zhí)行時就將DLL文件加載到應用程序當中。實現(xiàn)隱式鏈接很容易,只要將導入函數(shù)關鍵字_declspec(dllimport)函數(shù)名等寫到應用程序相應的頭文件中就可以了。下面的例子通過隱式鏈接調(diào)用MyDll.dll庫中的Min函數(shù)。首先生成一個項目為TestDll,在 DllTest.h、DllTest.cpp文件中分別輸入如下代碼:01 /Dlltest.h02 #pragma comment(lib,MyDll.lib)03 extern C_de

6、clspec(dllimport) int Max(int a,int b);04 extern C_declspec(dllimport) int Min(int a,int b);05 /TestDll.cpp06 #include07 #includeDlltest.h08 void main()09 10 int a;11 a=min(8,10)12 printf(比較的結果為%dn,a);13 在創(chuàng)建DllTest.exe文件之前,要先將MyDll.dll和MyDll.lib拷貝到當前工程所在的目錄下面,也可以拷貝到windows的 System目錄下。如果DLL使用的是def文件,

7、要刪除TestDll.h文件中關鍵字extern C。TestDll.h文件中的關鍵字Progam commit是要Visual C+的編譯器在link時,鏈接到MyDll.lib文件,當然,開發(fā)人員也可以不使用#pragma comment(lib,MyDll.lib)語句,而直接在工程的Setting-Link頁的Object/Moduls欄填入 MyDll.lib既可。編程時用ad.h,ad.lib,放在項目當前目錄里在頭文件中加入#include ad.h在Project SettingLinkObject/library modules加入ad.lib執(zhí)行時將ad.dll跟你的程序放

8、在同一目錄(二).顯式鏈接顯式鏈接是應用程序在執(zhí)行過程中隨時可以加載DLL文件,也可以隨時卸載DLL文件,這是隱式鏈接所無法作到的,所以顯式鏈接具有更好的靈活性,對于解釋性語言更為合適。不過實現(xiàn)顯式鏈接要麻煩一些。在應用程序中用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將自己所做的動態(tài)鏈接庫調(diào)進來,動態(tài)鏈接庫的文件名即是上述兩個函數(shù)的參數(shù),此后再用GetProcAddress()獲取想要引入的函數(shù)。自此,你就可以象使用如同在應用程序自定義的函數(shù)一樣來調(diào)用此引入函數(shù)了。在應用程序退出之前,應該用FreeLibrary或MFC提供的AfxFreeLibrary釋放動態(tài)鏈

9、接庫。下面是通過顯式鏈接調(diào)用DLL中的Max函數(shù)的例子。01 #include02 #include03 void main(void)04 05 typedef int(*pMax)(int a,int b);06 typedef int(*pMin)(int a,int b);07 HINSTANCE hDLL;08 PMax Max09 HDLL=LoadLibrary(MyDll.dll);/加載動態(tài)鏈接庫MyDll.dll文件;10 Max=(pMax)GetProcAddress(hDLL,Max);11 A=Max(5,8);12 Printf(比較的結果為%dn,a);13 F

10、reeLibrary(hDLL);/卸載MyDll.dll文件;14 在上例中使用類型定義關鍵字typedef,定義指向和DLL中相同的函數(shù)原型指針,然后通過LoadLibray()將DLL加載到當前的應用程序中并返回當前DLL文件的句柄,然后通過GetProcAddress()函數(shù)獲取導入到應用程序中的函數(shù)指針,函數(shù)調(diào)用完畢后,使用 FreeLibrary()卸載DLL文件。在編譯程序之前,首先要將DLL文件拷貝到工程所在的目錄或Windows系統(tǒng)目錄下。使用顯式鏈接應用程序編譯時不需要使用相應的Lib文件。另外,使用GetProcAddress()函數(shù)時,可以利用 MAKEINTRESOU

11、RCE()函數(shù)直接使用DLL中函數(shù)出現(xiàn)的順序號,如將GetProcAddress(hDLL,Min)改為 GetProcAddress(hDLL, MAKEINTRESOURCE(2)(函數(shù)Min()在DLL中的順序號是2),這樣調(diào)用DLL中的函數(shù)速度很快,但是要記住函數(shù)的使用序號,否則會發(fā)生錯誤。VC+ 6.0如何創(chuàng)建與調(diào)用動態(tài)鏈接庫出處:多特軟件站時間:2011-06-29人氣:1451我要提問我來說兩句核心提示:靜態(tài)鏈接庫:lib中的指令被直接包含在最終生成的EXE文件中。1.靜態(tài)鏈接庫與動態(tài)鏈接庫區(qū)別:靜態(tài)鏈接庫:lib中的指令被直接包含在最終生成的EXE文件中。動態(tài)鏈接庫:dll不必

12、被包含在最終的EXE中,EXE文件執(zhí)行時可以動態(tài)地引用和卸載DLL文件。同時,靜態(tài)鏈接庫中不能再包含其他的動態(tài)鏈接庫或靜態(tài)庫,而動態(tài)鏈接庫中可以包含其他的動態(tài)或靜態(tài)庫。2.VC+支持的DLL:DLL的編制與具體的編程語言及編譯器無關,動態(tài)鏈接庫隨處可見,VC+支持三種DLL:非MFC動態(tài)庫、MFC規(guī)則DLL和MFC擴展DLL。DLL導出函數(shù)(或變量、類)可供應用程序調(diào)用;DLL內(nèi)部函數(shù)只能在DLL程序內(nèi)使用,應用程序無法調(diào)用它們。3.導出函數(shù)的聲明方式:一種在函數(shù)聲明類型和函數(shù)名之間加上“_declspec(dllexport)”。另外一種采用模塊定義(.def)文件聲明,需要在庫工程中添加模

13、塊文件,格式如下:LIBRARY 庫工程名稱EXPORTS 導出函數(shù)名4.DLL的調(diào)用方式:一種靜態(tài)調(diào)用,由編譯系統(tǒng)完成對DLL的加載和應用程序結束時DLL的卸載。另外一種動態(tài)調(diào)用,由編程者用API函數(shù)加載和卸載DLL(DLL加載DLL函數(shù)地址獲取DLL釋放)方式。5.所有庫工程編譯時必須Release方式:Buildset active configuration選擇庫工程的release方式6.示例:一、 函數(shù)-創(chuàng)建動態(tài)鏈接庫(MFC規(guī)則DLL)1. New-projects-MFC AppWizard(dll)-Regular DLL using shared MFC DLL /取名為M

14、FC_dll2. def文件中添加:函數(shù)名(Add_new)3. h文件中添加:外部函數(shù)聲明/求和函數(shù),函數(shù)名為Add_newextern C _declspec(dllexport) int _stdcall Add_new(int a,int b);4. cpp文件中添加: 外部函數(shù)實現(xiàn)extern C _declspec(dllexport) int _stdcall Add_new(int a,int b)return a+b;5. build-set active configuration-win32 release-ok6. 生成7. 根目錄下release文件夾中dll,lib

15、與根目錄下h文件即為所需二、 函數(shù)-調(diào)用動態(tài)鏈接庫(把MFC_dll.dll和MFC_dll.lib拷到工程所在目錄)/靜態(tài)調(diào)用(.h可以寫到.cpp文件中)1. new-projects-win32 console application-an empty project2. 添加h文件:(test.h)#pragma comment(lib,MFC_dll.lib) /告訴編譯器DLL相對應的lib文件所在路徑和文件名extern C _declspec(dllimport) int _stdcall Add_new(int a,int b);/聲明導入函數(shù)3. 添加cpp文件:(main

16、.cpp)#include test.hint main()coutAdd_new(10,3);return 0;/動態(tài)調(diào)用#include #include typedef int (* lpAddFun)(int ,int);/定義一個與Add_new函數(shù)接受參數(shù)類型和返回值均相同的函數(shù)指針類型int main()HINSTANCE hDll;/句柄lpAddFun addFun;/函數(shù)指針hDll=LoadLibrary(dllTest.dll);/動態(tài)加載DLL模塊句柄if(hDll)addFun=(lpAddFun) GetProcAddress(hDll,Add_new);/得到所

17、加載DLL模塊中函數(shù)的地址if(addFun)int result=addFun(2,3);printf(%d,result); FreeLibrary(hDll);/釋放已經(jīng)加載的DLL模塊return 0;三、 變量-創(chuàng)建動態(tài)鏈接庫(非MFC DLL)1. new-projects-win32 dynamic-link library-an empty project(Sample)2. 添加sample.h#ifndef SAMPLE_H#define SAMPLE_Hextern int dllGlobalVar;#endif3. 添加 sample.cpp#include sampl

18、e.h#include int dllGlobalVar;bool APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)/windows在加載DLL時,需要一個入口函數(shù),就如同控制臺或DOS程序需要main函數(shù)、win32程序需要winmain函數(shù)一樣。所以引入一個不做任何操作的缺省DllMain的函數(shù)版本。是DLL的內(nèi)部函數(shù)句柄,是整個windows編程的基礎,一個句柄是指使用的一個唯一的整數(shù)值,是指一個四字節(jié)長的數(shù)值,用于標志應用程序中的不同對象和同類對象中的不同的實例,諸如,一個窗口,按鈕,

19、圖標,滾動條,輸出設備,控件或者文件等,應用程序能夠通過句柄訪問相應的對象的信息。但是,句柄不是一個指針,程序不能利用它句柄來直接閱讀文件中的信息。如果句柄不用在I/O文件中,它是毫無用處的。 句柄是windows用來標志應用程序中建立的或是使用的唯一整數(shù),windows使用了大量的句柄來標志很多對象。句柄就是一個數(shù)字常量 用來標識指定一個窗體的,一個窗體有一個唯一的標識,引用句柄就可以引用窗體 例如:已知一個窗口的句柄HWND,如何強制關閉它,代碼如下SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0); 向窗口發(fā)送WM_CLOSE消息應該是可以的,如果

20、不行可能是因為窗口停止響應,可用如下方法: . DWORD dwThreadId,dwProcessId; HANDLE hProcess; dwThreadId = GetWindowThreadProcessId(hWnd,&dwProcessId); hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,dwProcessId); if(hProcess=NULL) return FALSE; / so bad ! TerminateProcess(hProcess);什么是句柄?為什么會有句柄?HANDLE 關鍵字:句柄, HANDLE, WIN

21、DOWS SDK, windows.h, 從廣義上,能夠從一個數(shù)值拎起一大堆數(shù)據(jù)的東西都可以叫做句柄。句柄的英文是Handle,本義就是柄,只是在計算機科學中,被特別地翻譯成句柄,其實還是個柄。從一個小東西拎起一大堆東西,這難道不像是個柄嗎? 然后,指針其實也是一種句柄,只是由于指針同時擁有更特殊的含義實實在在地對應內(nèi)存里地一個地址所以,通常不把指針說成是句柄。但指針也有著能從一個32位的值引用到一大堆數(shù)據(jù)的作用,這不是句柄又是什么? Windows系統(tǒng)中有許多內(nèi)核對象(這里的對象不完全等價于面向?qū)ο蟪绦蛟O計一詞中的對象,雖然實質(zhì)上還真差不多),比如打開的文件,創(chuàng)建的線程,程序的窗口,等等。這

22、些重要的對象肯定不是4個字節(jié)或者8個字節(jié)足以完全描述的,他們擁有大量的屬性。為了保存這樣一個對象的狀態(tài),往往需要上百甚至上千字節(jié)的內(nèi)存空間,那么怎么在程序間或程序內(nèi)部的子過程(函數(shù))之間傳遞這些數(shù)據(jù)呢?拖著這成百上千的字節(jié)拷貝來拷貝去嗎?顯然會浪費效率。那么怎么辦?當然傳遞這些對象的首地址是一個辦法,但這至少有兩個缺點: 1. 暴露了內(nèi)核對象本身,使得程序(而不是操作系統(tǒng)內(nèi)核)也可以任意地修改對象地內(nèi)部狀態(tài)(首地址都知道了,還有什么不能改的?),這顯然是操作系統(tǒng)內(nèi)核所不允許的; 2. 操作系統(tǒng)有定期整理內(nèi)存的責任,如果一些內(nèi)存整理過一次后,對象被搬走了怎么辦? 所以,Windows操作系統(tǒng)就采用進一步的間接:在進程的地址空間中設一張表,表里頭專門保存一些編號和由這個編號對應一個地址,而由那個地址去引用實際的對象,這個編號跟那個地址在數(shù)值上沒有任何規(guī)律性的聯(lián)系,純粹是個映射而已。 在Win

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論