




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、VC中使用動態鏈接庫DLL:靜態調用和動態調用2010-05-02 15:56VC中生成DLL的辦法見:-VC中使用DLL調用DLL有兩種方法:靜態調用和動態調用.(一).靜態調用其步驟如下:1.把你的youApp.DLL拷到你目標工程(需調用youApp.DLL的工程)的Debug目錄下;2.把你的youApp.lib拷到你目標工程(需調用youApp.DLL的工程)目錄下;3.把你的youApp.h(包含輸出函數的定義)拷到你目標工程(需調用youApp.DLL的工程)目錄下;4.打開你的目標工程選中工程,選擇Visual C+的Project主菜單的Settings菜單;5.執行第4步后
2、,VC將會彈出一個對話框,在對話框的多頁顯示控件中選擇Link頁。然后在Object/library modules輸入框中輸入:youApp.lib6.選擇你的目標工程Head Files加入:youApp.h文件;7.最后在你目標工程(*.cpp,需要調用DLL中的函數)中包含你的:#include youApp.h注:youApp是你DLL的工程名。(二).動態調用其程序如下:動態調用時只需做靜態調用步驟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 函數別名08 youFuntionNameAlias = (MYFUNC)GetProcAddress(hDllInst,youFuntionName);09 / youFuntionName 在DLL中聲明的函數名10 if(youFuntionNameAlias)11 12 youFuntionNameAlias(param1,param2);13 14 FreeLibrary(hDllInst);15 16 顯式(靜
4、態)調用:LIB + DLL + .H,注意.H中dllexport改為dllimport隱式(動態)調用:DLL + 函數原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數的地址),不用后FreeLibrary-動態鏈接庫DLL的鏈接應用程序使用DLL可以采用兩種方式:一種是隱式鏈接,另一種是顯式鏈接。在使用DLL之前首先要知道DLL中函數的結構信息。Visual C+6.0在VCbin目錄下提供了一個名為Dumpbin.exe的小程序,用它可以查看DLL文件中的函數結構。另外,Windows系統將遵循下面的搜索順序來定位DLL: 1包含EXE文件的目錄,
5、2進程的當前工作目錄, 3Windows系統目錄, 4Windows目錄,5列在Path環境變量中的一系列目錄。(一).隱式鏈接隱式鏈接就是在程序開始執行時就將DLL文件加載到應用程序當中。實現隱式鏈接很容易,只要將導入函數關鍵字_declspec(dllimport)函數名等寫到應用程序相應的頭文件中就可以了。下面的例子通過隱式鏈接調用MyDll.dll庫中的Min函數。首先生成一個項目為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 在創建DllTest.exe文件之前,要先將MyDll.dll和MyDll.lib拷貝到當前工程所在的目錄下面,也可以拷貝到windows的 System目錄下。如果DLL使用的是def文件,
7、要刪除TestDll.h文件中關鍵字extern C。TestDll.h文件中的關鍵字Progam commit是要Visual C+的編譯器在link時,鏈接到MyDll.lib文件,當然,開發人員也可以不使用#pragma comment(lib,MyDll.lib)語句,而直接在工程的Setting-Link頁的Object/Moduls欄填入 MyDll.lib既可。編程時用ad.h,ad.lib,放在項目當前目錄里在頭文件中加入#include ad.h在Project SettingLinkObject/library modules加入ad.lib執行時將ad.dll跟你的程序放
8、在同一目錄(二).顯式鏈接顯式鏈接是應用程序在執行過程中隨時可以加載DLL文件,也可以隨時卸載DLL文件,這是隱式鏈接所無法作到的,所以顯式鏈接具有更好的靈活性,對于解釋性語言更為合適。不過實現顯式鏈接要麻煩一些。在應用程序中用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將自己所做的動態鏈接庫調進來,動態鏈接庫的文件名即是上述兩個函數的參數,此后再用GetProcAddress()獲取想要引入的函數。自此,你就可以象使用如同在應用程序自定義的函數一樣來調用此引入函數了。在應用程序退出之前,應該用FreeLibrary或MFC提供的AfxFreeLibrary釋放動態鏈
9、接庫。下面是通過顯式鏈接調用DLL中的Max函數的例子。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);/加載動態鏈接庫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中相同的函數原型指針,然后通過LoadLibray()將DLL加載到當前的應用程序中并返回當前DLL文件的句柄,然后通過GetProcAddress()函數獲取導入到應用程序中的函數指針,函數調用完畢后,使用 FreeLibrary()卸載DLL文件。在編譯程序之前,首先要將DLL文件拷貝到工程所在的目錄或Windows系統目錄下。使用顯式鏈接應用程序編譯時不需要使用相應的Lib文件。另外,使用GetProcAddress()函數時,可以利用 MAKEINTRESOU
11、RCE()函數直接使用DLL中函數出現的順序號,如將GetProcAddress(hDLL,Min)改為 GetProcAddress(hDLL, MAKEINTRESOURCE(2)(函數Min()在DLL中的順序號是2),這樣調用DLL中的函數速度很快,但是要記住函數的使用序號,否則會發生錯誤。VC+ 6.0如何創建與調用動態鏈接庫出處:多特軟件站時間:2011-06-29人氣:1451我要提問我來說兩句核心提示:靜態鏈接庫:lib中的指令被直接包含在最終生成的EXE文件中。1.靜態鏈接庫與動態鏈接庫區別:靜態鏈接庫:lib中的指令被直接包含在最終生成的EXE文件中。動態鏈接庫:dll不必
12、被包含在最終的EXE中,EXE文件執行時可以動態地引用和卸載DLL文件。同時,靜態鏈接庫中不能再包含其他的動態鏈接庫或靜態庫,而動態鏈接庫中可以包含其他的動態或靜態庫。2.VC+支持的DLL:DLL的編制與具體的編程語言及編譯器無關,動態鏈接庫隨處可見,VC+支持三種DLL:非MFC動態庫、MFC規則DLL和MFC擴展DLL。DLL導出函數(或變量、類)可供應用程序調用;DLL內部函數只能在DLL程序內使用,應用程序無法調用它們。3.導出函數的聲明方式:一種在函數聲明類型和函數名之間加上“_declspec(dllexport)”。另外一種采用模塊定義(.def)文件聲明,需要在庫工程中添加模
13、塊文件,格式如下:LIBRARY 庫工程名稱EXPORTS 導出函數名4.DLL的調用方式:一種靜態調用,由編譯系統完成對DLL的加載和應用程序結束時DLL的卸載。另外一種動態調用,由編程者用API函數加載和卸載DLL(DLL加載DLL函數地址獲取DLL釋放)方式。5.所有庫工程編譯時必須Release方式:Buildset active configuration選擇庫工程的release方式6.示例:一、 函數-創建動態鏈接庫(MFC規則DLL)1. New-projects-MFC AppWizard(dll)-Regular DLL using shared MFC DLL /取名為M
14、FC_dll2. def文件中添加:函數名(Add_new)3. h文件中添加:外部函數聲明/求和函數,函數名為Add_newextern C _declspec(dllexport) int _stdcall Add_new(int a,int b);4. cpp文件中添加: 外部函數實現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文件即為所需二、 函數-調用動態鏈接庫(把MFC_dll.dll和MFC_dll.lib拷到工程所在目錄)/靜態調用(.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);/聲明導入函數3. 添加cpp文件:(main
16、.cpp)#include test.hint main()coutAdd_new(10,3);return 0;/動態調用#include #include typedef int (* lpAddFun)(int ,int);/定義一個與Add_new函數接受參數類型和返回值均相同的函數指針類型int main()HINSTANCE hDll;/句柄lpAddFun addFun;/函數指針hDll=LoadLibrary(dllTest.dll);/動態加載DLL模塊句柄if(hDll)addFun=(lpAddFun) GetProcAddress(hDll,Add_new);/得到所
17、加載DLL模塊中函數的地址if(addFun)int result=addFun(2,3);printf(%d,result); FreeLibrary(hDll);/釋放已經加載的DLL模塊return 0;三、 變量-創建動態鏈接庫(非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時,需要一個入口函數,就如同控制臺或DOS程序需要main函數、win32程序需要winmain函數一樣。所以引入一個不做任何操作的缺省DllMain的函數版本。是DLL的內部函數句柄,是整個windows編程的基礎,一個句柄是指使用的一個唯一的整數值,是指一個四字節長的數值,用于標志應用程序中的不同對象和同類對象中的不同的實例,諸如,一個窗口,按鈕,
19、圖標,滾動條,輸出設備,控件或者文件等,應用程序能夠通過句柄訪問相應的對象的信息。但是,句柄不是一個指針,程序不能利用它句柄來直接閱讀文件中的信息。如果句柄不用在I/O文件中,它是毫無用處的。 句柄是windows用來標志應用程序中建立的或是使用的唯一整數,windows使用了大量的句柄來標志很多對象。句柄就是一個數字常量 用來標識指定一個窗體的,一個窗體有一個唯一的標識,引用句柄就可以引用窗體 例如:已知一個窗口的句柄HWND,如何強制關閉它,代碼如下SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0); 向窗口發送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, 從廣義上,能夠從一個數值拎起一大堆數據的東西都可以叫做句柄。句柄的英文是Handle,本義就是柄,只是在計算機科學中,被特別地翻譯成句柄,其實還是個柄。從一個小東西拎起一大堆東西,這難道不像是個柄嗎? 然后,指針其實也是一種句柄,只是由于指針同時擁有更特殊的含義實實在在地對應內存里地一個地址所以,通常不把指針說成是句柄。但指針也有著能從一個32位的值引用到一大堆數據的作用,這不是句柄又是什么? Windows系統中有許多內核對象(這里的對象不完全等價于面向對象程序設計一詞中的對象,雖然實質上還真差不多),比如打開的文件,創建的線程,程序的窗口,等等。這
22、些重要的對象肯定不是4個字節或者8個字節足以完全描述的,他們擁有大量的屬性。為了保存這樣一個對象的狀態,往往需要上百甚至上千字節的內存空間,那么怎么在程序間或程序內部的子過程(函數)之間傳遞這些數據呢?拖著這成百上千的字節拷貝來拷貝去嗎?顯然會浪費效率。那么怎么辦?當然傳遞這些對象的首地址是一個辦法,但這至少有兩個缺點: 1. 暴露了內核對象本身,使得程序(而不是操作系統內核)也可以任意地修改對象地內部狀態(首地址都知道了,還有什么不能改的?),這顯然是操作系統內核所不允許的; 2. 操作系統有定期整理內存的責任,如果一些內存整理過一次后,對象被搬走了怎么辦? 所以,Windows操作系統就采用進一步的間接:在進程的地址空間中設一張表,表里頭專門保存一些編號和由這個編號對應一個地址,而由那個地址去引用實際的對象,這個編號跟那個地址在數值上沒有任何規律性的聯系,純粹是個映射而已。 在Win
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 上海四小考試試題及答案
- 寵物關系測試題及答案
- 財務管理高級應用試題及答案
- 答題演繹測試題及答案
- 2025年中級會計實務答題助手試題及答案
- 2025年財務管理考試經驗積累試題及答案
- 提升職業技能的個人規劃計劃
- 小班同伴關系的建立與促進計劃
- 解讀2025年工程法規考試的因素與規律試題及答案
- 生物科學素養培養策略計劃
- 妊娠期常見的皮膚病
- T∕CACM 1078-2018 中醫治未病技術操作規范 拔罐
- 糖尿病膳食指南2024
- 腹腔穿刺術評分表
- 2024屆上海市閔行區三年級英語第二學期期中監測模擬試題含答案
- 電氣一次主接線圖課件
- 創新創業教育的課程設計與實施研究
- 2024年重慶環衛集團有限公司招聘筆試參考題庫含答案解析
- 手機攝影培訓攝像教程拍照技巧技術含內容兩篇
- 【運動康復專業病例分析報告:腰間盤突出癥的術后康復運動療法設計5700字(論文)】
- Unit5Ourdreams(課件)重大版英語六年級下冊
評論
0/150
提交評論