VS2005下如何新建一个WINCE设备的DLL工程
一、???????動態鏈接庫簡介
1.1 DLL概述
動態鏈接庫(Dynamic Link Library, j簡稱DLL)是一些編譯過的可執行的程序模塊,可以在應用程序中或其他DLL中被調用。DLL應用非常廣泛,可以實現多個應用程序的代碼和資源共享,是WinCE程序設計中的一個非常重要的組成部分。
DLL設計程序的優點:
l?????????共享代碼、資源和數據。DLL作為一種基于Windows的程序模塊,不僅可以包含可執行代碼,還可以包括數據和各種資源等,擴大了庫文件的使用范圍;
l?????????可將系統模塊化,方便升級。
l?????????隱藏實現細節。
l?????????DLL與語言無關。
?1.2 DLL的調用
????不論使用何種語言對編譯好的DLL進行調用時,基本上都有兩種調用方式,即靜態調用方式和動態調用方式。靜態調用方式由編譯系統完成對DLL的加載和應用程序結束時DLL卸載的編碼(如還有其他程序使用該DLL,則Windows對DLL的應用記錄減1,直到所有相關程序都結束對該DLL的使用時才釋放它),簡單使用,但不靈活,只能滿足一般要求。動態調用方式是由編程者用API函數加載和卸載DLL來達到調用DLL的目的,使用上較復雜,但能更加有效地使用內存,是編制大型應用程序時的重要方式。
1.2.1 DLL的靜態調用
????DLL的靜態調用由編譯系統完成對DLL的加載和應用程序結束時DLL卸載,在VS2005中靜態調用DLL非常簡單:首先在VS2005的“工具->選項->項目和解決方案->VC++目錄”里設置庫文件的路徑;然后將需要的lib文件的名稱加入到“項目-〉屬性-〉配置屬性-〉連接器-〉輸入-〉附屬依賴項”,文件名稱之間用空格間隔;最后在使用DLL中的函數文件里引用DLL的頭文件(.h)即可。
????當開發人員通過靜態方式編譯并生成應用程序時,應用程序中的調用函數與LIB文件中的導出符號相匹配,這些符號或標示進入到生成的EXE文件中。當應用程序運行過程中需要加載DLL文件時,操作系統將根據這些信息查尋并加載DLL,然后通過符號或標示實現對DLL函數的動態鏈接。當加載應用程序的EXE文件時,所有被應用程序調用的DLL文件都被加載到內存中,這時可執行程序直接通過函數名調用DLL的輸出函數,其調用方法與調用程序內部函數相同。
????因此,如果設備上沒有應用程序所要加載的DLL庫時,用戶需自己將DLL庫拷貝到應用程序所在目錄,或系統根目錄。
1.2.2 DLL的動態調用
????????動態調用方式是由編程者用API函數加載和卸載DLL來達到調用DLL的目的,動態調用是指在應用程序中使用LoadLibrary函數或MFC提供的AfxLoadLibrary函數顯式調用自己所需要的動態鏈接庫,動態鏈接庫的文件名就是上面兩個函數的參數,然后在使用GetProAddress()函數獲取所需要引入的函數。完成上述操作后,應用程序可以調用引入的函數。在應用程序退出之前,應該使用FreeLibrary函數或MFC提供的AfxFreeLibrary函數來釋放動態鏈接庫。
二?DLL工程的實現
2.1?動態鏈接庫的創建
2.1.1
1、新建一個基于Smart Device的?MFC Smart Device DLL,將項目名稱設為eSOM9261API,如圖2-1所示。
圖?2-1?新建DLL工程名
2、?單擊OK,此時將出現DLL的支持平臺對話框,選擇所支持的平臺,由于我們這里的DLL動態庫使用eSOM/9261目標板,所以選擇EEIC08SDK(eSOM/9261產品自帶的SDK包)平臺。如圖2-2所示。
圖?2-2?平臺選擇
3、?單擊Next,將出現DLL的類型選擇(如圖2-3所示),選中MFC Extension DLL,按Finish可完成DLL向導工作。此時向導將自動生成DLL基本框架。
圖?2-3 DLL類型選擇
2.1.2
每個DLL必須有一個入口點,這就如如同使用C語言編寫的應用程序必須有一個main函數一樣,DllMain是一個默認的入口函數,它負責初始化和結束工作,當一個新的線程訪問DLL時,都會調用DllMain函數。
????打開利用向導生成的eSOM9261API.cpp文件,即可看到DllMain函數的實現。
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?輸出函數的實現方法
????DLL中導出函數的聲明有兩種方式:一種方法在函數名稱聲明中加上修飾符__declspec(dllexport),表示輸出,此外,還有一種修飾符?extern "C"??__declspec(dllexport),也表示輸出,而且該類DLL不僅可以被C++調用,還可以被C調用。在C++下定義C函數時,需要加上extern "C"關鍵字。下面為DLL測試程序的輸出函數的聲明。(在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);
}
????對應的原文件(eSOM9261API.c)的實現函數如下:
void?SetBuzz(void)
{
????return;
}
void?ClearBuzz (void)
{
????return;
}
導出函數另外一種方式是采用模塊定義(.def)?文件聲明,.def文件為鏈接器提供了有關被鏈接程序的導出、屬性及其他方面的信息。(eSOM9261API.def的內容)
; eSOM9261API.def : Declares the module parameters for the DLL.
LIBRARY??????"eSOM9261API"
?
EXPORTS
????SetBuzz
????ClearBuzz??
????采用模塊定義.def導出函數聲明,如果要求導出函數能夠被C語言掉用,必須在函數的實現前加?extern "C"進行修飾。
extern?"C"?void?SetBuzz?(void)
{??
????return ;
}
2.2?動態鏈接庫的調用
2.2.1?靜態調用DLL的步驟
????利用VS2005生成一個DLL調用測試應用程序eSOM9261Test.sln,并將上述編譯好的eSOM9261API.dll和eSOM9261API.lib文件拷貝到本工程的目錄下。然后使用VS2005的Project->Properties屬性設置中,選中Linker,在Linker的Input選項的Additional Dependencies中輸入eSOM9261API.lib如圖2-4所示
圖?2-4?應用程序引入動態鏈接庫文件
????如果在DLL的函數的導出采用頭文件的實現方法,必須將DLL的頭文件eSOM9261API.h拷貝到在調用DLL的工程中,并在實現文件中引用eSOM9261API.h文件,代碼如下:
#include?"eSOM9261API.h"
這樣就可以使用DLL的導出函數。
????如果采用模塊(.def)導出DLL中實現函數,則必須在調用DLL的實現文件聲明導入函數,代碼如下:
extern?"C"??void?__declspec(dllimport) SetBuzz(void);
extern?"C"??void?__declspec(dllimport) ClearBuzz(void);
2.2.2?動態調用DLL的步驟
????動態調用方式是使用LoadLibrary API函數加載DLL,然后在使用GetProAddress()函數獲取所需要引入的函數。
具體實現方式:
l?????????添加eSOM9261Test動態鏈接庫工程的實現函數的定義,代碼如下:
typedef void (*pSetBuzz)??(void);
typedef void (*pClearBuzz) (void);
利用LoadLibrary API函數動態加載動態鏈接庫,代碼的黑體部分;
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函數獲取需要引用的函數,代碼如下:
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();
}
?
總結
以上是生活随笔為你收集整理的VS2005下如何新建一个WINCE设备的DLL工程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将SVN与BUG跟踪管理集成
- 下一篇: 创建WINCE6.0设备的DLL工程