VS2005下如何新建一个WINCE设备的DLL工程
一、???????動(dòng)態(tài)鏈接庫簡介
1.1 DLL概述
動(dòng)態(tài)鏈接庫(Dynamic Link Library, j簡稱DLL)是一些編譯過的可執(zhí)行的程序模塊,可以在應(yīng)用程序中或其他DLL中被調(diào)用。DLL應(yīng)用非常廣泛,可以實(shí)現(xiàn)多個(gè)應(yīng)用程序的代碼和資源共享,是WinCE程序設(shè)計(jì)中的一個(gè)非常重要的組成部分。
DLL設(shè)計(jì)程序的優(yōu)點(diǎn):
l?????????共享代碼、資源和數(shù)據(jù)。DLL作為一種基于Windows的程序模塊,不僅可以包含可執(zhí)行代碼,還可以包括數(shù)據(jù)和各種資源等,擴(kuò)大了庫文件的使用范圍;
l?????????可將系統(tǒng)模塊化,方便升級(jí)。
l?????????隱藏實(shí)現(xiàn)細(xì)節(jié)。
l?????????DLL與語言無關(guān)。
?1.2 DLL的調(diào)用
????不論使用何種語言對編譯好的DLL進(jìn)行調(diào)用時(shí),基本上都有兩種調(diào)用方式,即靜態(tài)調(diào)用方式和動(dòng)態(tài)調(diào)用方式。靜態(tài)調(diào)用方式由編譯系統(tǒng)完成對DLL的加載和應(yīng)用程序結(jié)束時(shí)DLL卸載的編碼(如還有其他程序使用該DLL,則Windows對DLL的應(yīng)用記錄減1,直到所有相關(guān)程序都結(jié)束對該DLL的使用時(shí)才釋放它),簡單使用,但不靈活,只能滿足一般要求。動(dòng)態(tài)調(diào)用方式是由編程者用API函數(shù)加載和卸載DLL來達(dá)到調(diào)用DLL的目的,使用上較復(fù)雜,但能更加有效地使用內(nèi)存,是編制大型應(yīng)用程序時(shí)的重要方式。
1.2.1 DLL的靜態(tài)調(diào)用
????DLL的靜態(tài)調(diào)用由編譯系統(tǒng)完成對DLL的加載和應(yīng)用程序結(jié)束時(shí)DLL卸載,在VS2005中靜態(tài)調(diào)用DLL非常簡單:首先在VS2005的“工具->選項(xiàng)->項(xiàng)目和解決方案->VC++目錄”里設(shè)置庫文件的路徑;然后將需要的lib文件的名稱加入到“項(xiàng)目-〉屬性-〉配置屬性-〉連接器-〉輸入-〉附屬依賴項(xiàng)”,文件名稱之間用空格間隔;最后在使用DLL中的函數(shù)文件里引用DLL的頭文件(.h)即可。
????當(dāng)開發(fā)人員通過靜態(tài)方式編譯并生成應(yīng)用程序時(shí),應(yīng)用程序中的調(diào)用函數(shù)與LIB文件中的導(dǎo)出符號(hào)相匹配,這些符號(hào)或標(biāo)示進(jìn)入到生成的EXE文件中。當(dāng)應(yīng)用程序運(yùn)行過程中需要加載DLL文件時(shí),操作系統(tǒng)將根據(jù)這些信息查尋并加載DLL,然后通過符號(hào)或標(biāo)示實(shí)現(xiàn)對DLL函數(shù)的動(dòng)態(tài)鏈接。當(dāng)加載應(yīng)用程序的EXE文件時(shí),所有被應(yīng)用程序調(diào)用的DLL文件都被加載到內(nèi)存中,這時(shí)可執(zhí)行程序直接通過函數(shù)名調(diào)用DLL的輸出函數(shù),其調(diào)用方法與調(diào)用程序內(nèi)部函數(shù)相同。
????因此,如果設(shè)備上沒有應(yīng)用程序所要加載的DLL庫時(shí),用戶需自己將DLL庫拷貝到應(yīng)用程序所在目錄,或系統(tǒng)根目錄。
1.2.2 DLL的動(dòng)態(tài)調(diào)用
????????動(dòng)態(tài)調(diào)用方式是由編程者用API函數(shù)加載和卸載DLL來達(dá)到調(diào)用DLL的目的,動(dòng)態(tài)調(diào)用是指在應(yīng)用程序中使用LoadLibrary函數(shù)或MFC提供的AfxLoadLibrary函數(shù)顯式調(diào)用自己所需要的動(dòng)態(tài)鏈接庫,動(dòng)態(tài)鏈接庫的文件名就是上面兩個(gè)函數(shù)的參數(shù),然后在使用GetProAddress()函數(shù)獲取所需要引入的函數(shù)。完成上述操作后,應(yīng)用程序可以調(diào)用引入的函數(shù)。在應(yīng)用程序退出之前,應(yīng)該使用FreeLibrary函數(shù)或MFC提供的AfxFreeLibrary函數(shù)來釋放動(dòng)態(tài)鏈接庫。
二?DLL工程的實(shí)現(xiàn)
2.1?動(dòng)態(tài)鏈接庫的創(chuàng)建
2.1.1
1、新建一個(gè)基于Smart Device的?MFC Smart Device DLL,將項(xiàng)目名稱設(shè)為eSOM9261API,如圖2-1所示。
圖?2-1?新建DLL工程名
2、?單擊OK,此時(shí)將出現(xiàn)DLL的支持平臺(tái)對話框,選擇所支持的平臺(tái),由于我們這里的DLL動(dòng)態(tài)庫使用eSOM/9261目標(biāo)板,所以選擇EEIC08SDK(eSOM/9261產(chǎn)品自帶的SDK包)平臺(tái)。如圖2-2所示。
圖?2-2?平臺(tái)選擇
3、?單擊Next,將出現(xiàn)DLL的類型選擇(如圖2-3所示),選中MFC Extension DLL,按Finish可完成DLL向?qū)Чぷ鳌4藭r(shí)向?qū)⒆詣?dòng)生成DLL基本框架。
圖?2-3 DLL類型選擇
2.1.2
每個(gè)DLL必須有一個(gè)入口點(diǎn),這就如如同使用C語言編寫的應(yīng)用程序必須有一個(gè)main函數(shù)一樣,DllMain是一個(gè)默認(rèn)的入口函數(shù),它負(fù)責(zé)初始化和結(jié)束工作,當(dāng)一個(gè)新的線程訪問DLL時(shí),都會(huì)調(diào)用DllMain函數(shù)。
????打開利用向?qū)傻膃SOM9261API.cpp文件,即可看到DllMain函數(shù)的實(shí)現(xiàn)。
extern?"C"?BOOL APIENTRY
DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
{
????// Remove this if you use lpReserved
????UNREFERENCED_PARAMETER(lpReserved);
?
????if?(dwReason == DLL_PROCESS_ATTACH)
????{
????????TRACE0("eSOM9261API.DLL Initializing!/n");
???????
????????// Extension DLL one-time initialization
????????if?(!AfxInitExtensionModule(eSOM9261APIDLL,?reinterpret_cast<HMODULE>(hInstance)))
????????????return?0;
????????new?CDynLinkLibrary(eSOM9261APIDLL);
????}
????else?if?(dwReason == DLL_PROCESS_DETACH)
????{
????????TRACE0("eSOM9261API.DLL Terminating!/n");
????????// Terminate the library before destructors are called
????????AfxTermExtensionModule(eSOM9261APIDLL);
????}
????return?1;???// ok
}
2.1.3?輸出函數(shù)的實(shí)現(xiàn)方法
????DLL中導(dǎo)出函數(shù)的聲明有兩種方式:一種方法在函數(shù)名稱聲明中加上修飾符__declspec(dllexport),表示輸出,此外,還有一種修飾符?extern "C"??__declspec(dllexport),也表示輸出,而且該類DLL不僅可以被C++調(diào)用,還可以被C調(diào)用。在C++下定義C函數(shù)時(shí),需要加上extern "C"關(guān)鍵字。下面為DLL測試程序的輸出函數(shù)的聲明。(在eSOM9261API.h文件中)。
#ifdef ESOM9261API_EXPORTS
#define ESOM9261API_API _declspec(dllexport)
#else
#define ESOM9261API_API _declspec(dllimport)
#endif
?
extern "C"
{
????void ESOM9261API_API SetBuzz(void);
????void ESOM9261API_API ClearBuzz(void);
}
????對應(yīng)的原文件(eSOM9261API.c)的實(shí)現(xiàn)函數(shù)如下:
void?SetBuzz(void)
{
????return;
}
void?ClearBuzz (void)
{
????return;
}
導(dǎo)出函數(shù)另外一種方式是采用模塊定義(.def)?文件聲明,.def文件為鏈接器提供了有關(guān)被鏈接程序的導(dǎo)出、屬性及其他方面的信息。(eSOM9261API.def的內(nèi)容)
; eSOM9261API.def : Declares the module parameters for the DLL.
LIBRARY??????"eSOM9261API"
?
EXPORTS
????SetBuzz
????ClearBuzz??
????采用模塊定義.def導(dǎo)出函數(shù)聲明,如果要求導(dǎo)出函數(shù)能夠被C語言掉用,必須在函數(shù)的實(shí)現(xiàn)前加?extern "C"進(jìn)行修飾。
extern?"C"?void?SetBuzz?(void)
{??
????return ;
}
2.2?動(dòng)態(tài)鏈接庫的調(diào)用
2.2.1?靜態(tài)調(diào)用DLL的步驟
????利用VS2005生成一個(gè)DLL調(diào)用測試應(yīng)用程序eSOM9261Test.sln,并將上述編譯好的eSOM9261API.dll和eSOM9261API.lib文件拷貝到本工程的目錄下。然后使用VS2005的Project->Properties屬性設(shè)置中,選中Linker,在Linker的Input選項(xiàng)的Additional Dependencies中輸入eSOM9261API.lib如圖2-4所示
圖?2-4?應(yīng)用程序引入動(dòng)態(tài)鏈接庫文件
????如果在DLL的函數(shù)的導(dǎo)出采用頭文件的實(shí)現(xiàn)方法,必須將DLL的頭文件eSOM9261API.h拷貝到在調(diào)用DLL的工程中,并在實(shí)現(xiàn)文件中引用eSOM9261API.h文件,代碼如下:
#include?"eSOM9261API.h"
這樣就可以使用DLL的導(dǎo)出函數(shù)。
????如果采用模塊(.def)導(dǎo)出DLL中實(shí)現(xiàn)函數(shù),則必須在調(diào)用DLL的實(shí)現(xiàn)文件聲明導(dǎo)入函數(shù),代碼如下:
extern?"C"??void?__declspec(dllimport) SetBuzz(void);
extern?"C"??void?__declspec(dllimport) ClearBuzz(void);
2.2.2?動(dòng)態(tài)調(diào)用DLL的步驟
????動(dòng)態(tài)調(diào)用方式是使用LoadLibrary API函數(shù)加載DLL,然后在使用GetProAddress()函數(shù)獲取所需要引入的函數(shù)。
具體實(shí)現(xiàn)方式:
l?????????添加eSOM9261Test動(dòng)態(tài)鏈接庫工程的實(shí)現(xiàn)函數(shù)的定義,代碼如下:
typedef void (*pSetBuzz)??(void);
typedef void (*pClearBuzz) (void);
利用LoadLibrary API函數(shù)動(dòng)態(tài)加載動(dòng)態(tài)鏈接庫,代碼的黑體部分;
BOOL CTestDllDlg::OnInitDialog()
{
????CDialog::OnInitDialog();
????SetIcon(m_hIcon, TRUE);?????????// Set big icon
????SetIcon(m_hIcon, FALSE);????????// Set small icon
????hModule=LoadLibrary(_T("eSOM9261API.dll"));
????if(hModule==NULL)
???????MessageBox(_T("Load Dll file failed"),_T("System Information"),MB_OK|MB_ICONERROR);
????return?TRUE;??// return TRUE??unless you set the focus to a control
}
l?????????利用GetProcAddress API函數(shù)獲取需要引用的函數(shù),代碼如下:
void?CTestDllDlg::OnBnClickedbtnstop()
{
????pSetBuzz?SetBuzz =(pLedControl)GetProcAddress (hModule,_T("SetBuzz"));
????if(LedControl==NULL)
MessageBox(_T("Load LedControl function failed"),_T("System Information"),MB_OK|MB_ICONERROR);
????else
????????SetBuzz();
}
?
總結(jié)
以上是生活随笔為你收集整理的VS2005下如何新建一个WINCE设备的DLL工程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将SVN与BUG跟踪管理集成
- 下一篇: 创建WINCE6.0设备的DLL工程