VC++和基于Lab Windows/CVI的DLL在測控技術(shù)中的應(yīng)用
時間:2008-08-20 11:00:00來源:ronggang
導(dǎo)語:?介紹了動態(tài)鏈接庫(DLL)的運行機制,闡述了基于Lab Windows/CVI的DLL的開發(fā)以及它和VC++程序的集成方法,對于兩種程序之間的通訊,給出了一種基于內(nèi)存映射的實現(xiàn)方法
摘 要:介紹了動態(tài)鏈接庫(DLL)的運行機制,闡述了基于Lab Windows/CVI的DLL的開發(fā)以及它和VC++程序的集成方法,對于兩種程序之間的通訊,給出了一種基于內(nèi)存映射的實現(xiàn)方法。文章最后給出了一個技術(shù)上具體實現(xiàn)的例子加以說明。
關(guān)鍵詞: 虛擬儀器;Lab Windows/CVI;DLL;內(nèi)存映射
1、引言
大型測控系統(tǒng)的軟件系統(tǒng)通常采用高級語言結(jié)合專用測控軟件來開發(fā)。如何將不同的軟件程序加以集成,以及如何在它們之間進行通訊是必須解決的問題。
虛擬儀器測控系統(tǒng)中關(guān)鍵工作就是對數(shù)據(jù)的采集、分析、處理并模擬真實儀器面板的功能。由于VC++等高級語言的非針對性,采用其實現(xiàn)起來不僅復(fù)雜(如創(chuàng)建儀器面板,數(shù)據(jù)分析等),而且有些功能無法實現(xiàn),源代碼效率也較低;若采用Lab Windows/CVI,不僅開發(fā)方便,而且直觀,有些開發(fā)工作只需幾行代碼即可完成,可以大大提高系統(tǒng)開發(fā)的效率,節(jié)約時間。在筆者所參與的測控系統(tǒng)的開發(fā)中,采用的是用VC++開發(fā)系統(tǒng)軟件主干程序,負責(zé)系統(tǒng)軟件各方面的調(diào)度、管理,采用Lab Windows/CVI開發(fā)具體的測控功能,以具有不同功能的DLL形式組成測試功能模塊庫,集成到主干程序中實現(xiàn)各種不同的測控功能,采用內(nèi)存映射實現(xiàn)兩種程序間通訊和數(shù)據(jù)傳輸。
2、Lab Windows/CVI中DLL的開發(fā)
2.1 Lab Windows/CVI中DLL的開發(fā)方式及其運行機制
在CVI環(huán)境下,開發(fā)用于測控領(lǐng)域的動態(tài)鏈接庫,需將編譯目標文件類型設(shè)置為DLL,并設(shè)置DLL名稱、存儲路徑、DLL函數(shù)/變量導(dǎo)出方式等,才能通過Create Debuggable Dynamic Link Library生成DLL工程。
DLL不是可執(zhí)行文件,它需要由應(yīng)用程和另外的DLL調(diào)用執(zhí)行。一個程序使用DLL,它只能通過這個DLL的導(dǎo)出函數(shù)/變量訪問其內(nèi)部。在Lab Windows/CVI下創(chuàng)建DLL,有兩種方式導(dǎo)出函數(shù)/變量:頭文件法和導(dǎo)出關(guān)鍵字法。頭文件法使用頭文件確定要輸出的標號,頭文件中必須包含要導(dǎo)出標號的聲明;導(dǎo)出關(guān)鍵字法把每一個要導(dǎo)出的函數(shù)和變量都標記一個關(guān)鍵字,如__cdecl、__stdcall等,根據(jù)不同的編譯器使用不同的導(dǎo)出關(guān)鍵字。在DLL中只有被導(dǎo)出的函數(shù)/變量才能被外界所使用,所以只有指定DLL的導(dǎo)出函數(shù)/變量,該DLL才具有實際的使用意義。
DLL被調(diào)用時,它有自己的運行機制:每一個DLL都有一個DLLMain主函數(shù),在進入和退出DLL時,應(yīng)用程序分別調(diào)用這個函數(shù),它常常被用來執(zhí)行進程的初始化和清理工作。因為在該函數(shù)中定義了兩個事件句柄——DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH。當一個DLL被調(diào)用,即它被首次映射到進程的地址空間時,系統(tǒng)觸發(fā)DLL_PROCESS_ATTACH事件,一般在這部分執(zhí)行特定進程的DLL初始化工作,如調(diào)用InitCVIRTE()函數(shù)初始化引擎等;當應(yīng)用程序結(jié)束DLL的調(diào)用時,系統(tǒng)觸發(fā)DLL_PROCESS_DETACH事件,一般在這部分進行退出DLL時前的資源清理工作,如調(diào)用CloseCVIRTE ()釋放被DLL所占用的內(nèi)存。另外,CVI還提供了一個RunStateCallback()函數(shù)來對程序的執(zhí)行情況進行記錄,使用時通過該函數(shù)也可以控制程序的執(zhí)行及系統(tǒng)資源分配。
2.2工程中DLL的開發(fā)
筆者所參與的測控系統(tǒng)的開發(fā)中, DLL開發(fā)采用的是另外一種方式,由于DLL本身的不可執(zhí)行性,調(diào)試上沒有可執(zhí)行文件方便,而且工程上需要在導(dǎo)出的DLL中包含虛擬儀器軟面板,且保持軟面板對虛擬儀器的控制性,因此,在實際的開發(fā)中,先編寫CVI用于實現(xiàn)具體測控功能的可執(zhí)行文件,調(diào)試成功后,把該可執(zhí)行文件改成具有相同功能的DLL。改編時,僅僅對源文件(.c文件)的main函數(shù)做一些改變,并在頭文件(.h文件)中輸出,而無需做多的改變即可導(dǎo)出儀器軟面板,這樣在VC++主干程序調(diào)用該DLL時就可以方便的進行測控工作。
具體操作上:
?。?)首先編寫滿足測控要求的CVI的可執(zhí)行文件并調(diào)試成功;
?。?)在工程文件中打開包含工程主函數(shù)main()的.c文件,向文件中插入DLL所必須的DLLMain函數(shù)。
?。?)改寫.c文件中的main函數(shù)。修改其函數(shù)名及參數(shù),將其參數(shù)改為Windows的實例句柄HINSTANCE,它指向DLL被調(diào)用時DLL被映射到的進程的地址空間。另外由于調(diào)用時要使用儀器軟面板,就必須導(dǎo)出相應(yīng)的.uir函數(shù),因此main中的編譯環(huán)境默認的Loadpanel函數(shù)要用LoadpanelEx替代,因為使用Loadpanel函數(shù)時,用戶界面庫無法找到在.uir文件中定義的但沒有被DLL輸出的那些回調(diào)函數(shù),從而使DLL在被調(diào)用時出錯。對于LoadpanelEx,因為使用CVI編寫DLL時,CVI自動在工程中生成一個.uir中的回調(diào)函數(shù)列表,DLL被調(diào)用時,LoadpanelEx首先在此列表中進行查找,它可以實現(xiàn)回調(diào)函數(shù)的導(dǎo)出,從而保證在DLL中軟面板對虛擬儀器的正??刂啤?
(4)將修改后的main函數(shù)的聲明加入到原工程的頭文件。
(5)選擇頭文件導(dǎo)出法,編譯成DLL文件。
經(jīng)過改編后原工程就變成了可以由VC++主干程序調(diào)用的DLL,而它的所有測試功能都沒有變。事實證明,因為這種創(chuàng)建DLL的方法不需要增加額外的程序進行代碼調(diào)試,它比一般的直接創(chuàng)建方法要有效的多。
3 VC++應(yīng)用程序?qū)LL的調(diào)用
3.1 VC程序調(diào)用DLL的兩種方式
VC中鏈接DLL到應(yīng)用程序中有兩種方式:隱式鏈接和顯式鏈接。隱式鏈接時,使用DLL的可執(zhí)行程序鏈接到DLL導(dǎo)入庫(.lib文件)中,導(dǎo)入庫中包含了DLL中的每個導(dǎo)出符合和序號。當加載使用DLL的可執(zhí)行程序時,操作系統(tǒng)同時加載DLL。為了隱式鏈接DLL,可執(zhí)行程序需要從DLL提供者獲取以下內(nèi)容:包含導(dǎo)出函數(shù)聲明的頭文件(.h),導(dǎo)入庫(.lib)文件和實際的DLL(.dll)文件。顯示鏈接時,使用DLL的可執(zhí)行程序在運行時通過函數(shù)調(diào)用來顯式加載或卸載DLL,并通過函數(shù)指針來調(diào)用DLL的導(dǎo)出函數(shù),應(yīng)用程序通過Loadlibrary函數(shù)來加載DLL并獲取模塊句柄;通過GetProcessAddress來獲取應(yīng)用程序要調(diào)用的導(dǎo)出函數(shù)的指針。
工程中筆者采用的是顯式鏈接方式調(diào)用DLL,與隱式鏈接相比,顯示鏈接較靈活,在這種方式下,我們可以決定什么時候裝載和卸去DLL,以及決定加載哪個DLL,可以節(jié)約系統(tǒng)資源,代碼執(zhí)行效率高。
3.2 VC程序與測試模塊間的通信
在用VC++調(diào)用CVI的DLL時,存在著在不同軟件程序間的數(shù)據(jù)傳遞問題,工程中VC++程序是主干,它調(diào)用DLL,因此它的變量對DLL來說都是透明的、可用的;但是由Lab Windows/CVI開發(fā)的DLL文件生成的導(dǎo)出庫文件(.lib)不包含導(dǎo)出變量,因此DLL中的變量值,VC++不能直接獲得。工程中采用創(chuàng)建內(nèi)存映射文件的方法來實現(xiàn)二者之間的數(shù)據(jù)傳遞。所謂內(nèi)存映射文件是指在內(nèi)存中申請一塊內(nèi)存空間,將一個文件與這塊空間相聯(lián)系,再進行內(nèi)存映射,這樣操作文件就有和操作內(nèi)存一樣的效率,數(shù)據(jù)可以通過該映射文件進行中轉(zhuǎn)(寫入和讀出),幾個進程可通過操作該映射文件,實現(xiàn)進程間在內(nèi)存一級的高速數(shù)據(jù)交互。
具體方法為:首先在DLL中通過API函數(shù)CreateFileMapping及MapViewOfFile在內(nèi)存中建立一個文件映射對象并產(chǎn)生它的一個視,然后通過CopyMemory將測控數(shù)據(jù)存入
該視中,然后應(yīng)用程序就可使用OpenFileMapping打開該映射文件并對其進行讀寫操作,從而實現(xiàn)二者間通信。
4 代碼實例
限于篇幅,文中只給出部分重要的程序代碼。
4.1 CVI中程序代碼
1)對源文件的main函數(shù)進行改寫:
int main1 (HINSTANCE CVIUserHInst)// 修改函數(shù)名以及參數(shù)
{
if ((panelHandle = LoadPanelEx (0, "get.uir", PANEL,__CVIUserHInst)) < 0) //使用loadPanelEx函數(shù)可導(dǎo)出回調(diào)函數(shù)
return -1;
……
return 0;
?。?
?。?)創(chuàng)建內(nèi)存映射文件并拷入數(shù)據(jù)
hValue=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,0x300,"MapFile");//建立文件映射對象,MapFile為 映射文件名
……
ipmid=(mid*)MapViewOfFile(hValue,
FILE_MAP_ALL_ACCESS,0,0,0);//創(chuàng)建映射對象的一個視,mid為測控數(shù)據(jù)類型
……
CopyMemory(ipmid,&data,sizeof(mid));//將數(shù)據(jù)拷貝到共享的內(nèi)存中
?。?)在.h文件中加入修改后的main函數(shù)的導(dǎo)出聲明
int main1 (HINSTANCE CVIUserHInst);
4.2 VC中程序代碼
typedef int(*main1)(HINSTANCE); HINSTANCE USEInst;
USEInst=LoadLibrary("sousuoleidafashe_dbg.dll"); //加載DLL
main1 main; main=(main1)GetProcAddress(USEInst,
"main1");//得到DLL中導(dǎo)出函數(shù)main1的地址
main(USEInst);//執(zhí)行main1,調(diào)出儀器軟面板進行測試,測控數(shù)據(jù)寫入”MapFile”中
FreeLibrary(USEInst);
HValue=OpenFileMapping(…);//打開映射文件”MapFile”
ipmid=(mid*)MapViewOfFile(hValue;
FILE_MAP_ALL_ACCESS,0,0,0); //得到測試數(shù)據(jù)
至此,就完成了LabWindows/CVI中的DLL開發(fā)和VC++主干程序?qū)λ恼{(diào)用工作以及數(shù)據(jù)傳送工作。
5 結(jié)束語
本文介紹了一種把VC++和LabWindows/CVI結(jié)合起來進行測控系統(tǒng)開發(fā)的方法,根據(jù)兩種開發(fā)工具各自的優(yōu)缺點,取VC++對數(shù)據(jù)庫、多媒體等的強大的開發(fā)能力和它廣泛的適用性,結(jié)合LabWindows/CVI對測控數(shù)據(jù)強大的分析處理能力和它簡單直觀的儀器軟面板設(shè)計方法。實踐證明這種方法是完全可行的。
6 參考文獻
[1]NI Corporation.LabWindows/CVI User Interface Reference Manual [M/CD], 1996.
[2] 張磊, 虛擬儀器測試系統(tǒng)中實現(xiàn)數(shù)據(jù)共享的方法[J],計算機自動測量與控制, 2000年第05 期:58-60
[3] 白鳳山,動態(tài)連接庫(DLL)在虛擬儀器中的應(yīng)用[J],自動化與儀表,第16卷,2001年第01期:21-22
[4] [美]David J.Kruglinski,Visual C++ 技術(shù)內(nèi)幕[M],北京,清華大學(xué)出版社,1999年
標簽:
中國傳動網(wǎng)版權(quán)與免責(zé)聲明:凡本網(wǎng)注明[來源:中國傳動網(wǎng)]的所有文字、圖片、音視和視頻文件,版權(quán)均為中國傳動網(wǎng)(m.u63ivq3.com)獨家所有。如需轉(zhuǎn)載請與0755-82949061聯(lián)系。任何媒體、網(wǎng)站或個人轉(zhuǎn)載使用時須注明來源“中國傳動網(wǎng)”,違反者本網(wǎng)將追究其法律責(zé)任。
本網(wǎng)轉(zhuǎn)載并注明其他來源的稿件,均來自互聯(lián)網(wǎng)或業(yè)內(nèi)投稿人士,版權(quán)屬于原版權(quán)人。轉(zhuǎn)載請保留稿件來源及作者,禁止擅自篡改,違者自負版權(quán)法律責(zé)任。