VC++和基于Lab Windows/CVI的DLL在測控技術(shù)中的應(yīng)用
閱讀:2276發(fā)布時(shí)間:2008-09-01
- 提供商
煙臺(tái)勾股通信技術(shù)有限公司
- 資料大小
0K
- 資料圖片
- 下載次數(shù)
0次
- 資料類型
- 瀏覽次數(shù)
2276次
- 免費(fèi)下載
1、引言
大型測控系統(tǒng)的軟件系統(tǒng)通常采用語言結(jié)合測控軟件來開發(fā)。如何將不同的軟件程序加以集成,以及如何在它們之間進(jìn)行通訊是必須解決的問題。
虛擬儀器測控系統(tǒng)中關(guān)鍵工作就是對數(shù)據(jù)的采集、分析、處理并模擬真實(shí)儀器面板的功能。由于vc++等語言的非針對性,采用其實(shí)現(xiàn)起來不僅復(fù)雜(如創(chuàng)建儀器面板,數(shù)據(jù)分析等),而且有些功能無法實(shí)現(xiàn),源代碼效率也較低;若采用lab windows/cvi,不僅開發(fā)方便,而且直觀,有些開發(fā)工作只需幾行代碼即可完成,可以大大提高系統(tǒng)開發(fā)的效率,節(jié)約時(shí)間。在筆者所參與的測控系統(tǒng)的開發(fā)中,采用的是用vc++開發(fā)系統(tǒng)軟件主干程序,負(fù)責(zé)系統(tǒng)軟件各方面的調(diào)度、管理,采用lab windows/cvi開發(fā)具體的測控功能,以具有不同功能的dll形式組成測試功能模塊庫,集成到主干程序中實(shí)現(xiàn)各種不同的測控功能,采用內(nèi)存映射實(shí)現(xiàn)兩種程序間通訊和數(shù)據(jù)傳輸。
2、lab windows/cvi中dll的開發(fā)
2.1 lab windows/cvi中dll的開發(fā)方式及其運(yùn)行機(jī)制
在cvi環(huán)境下,開發(fā)用于測控領(lǐng)域的動(dòng)態(tài)鏈接庫,需將編譯目標(biāo)文件類型設(shè)置為dll,并設(shè)置dll名稱、存儲(chǔ)路徑、dll函數(shù)/變量導(dǎo)出方式等,才能通過cr-eate debuggable dynamic link library生成dll工程。
dll不是可執(zhí)行文件,它需要由應(yīng)用程和另外的dll調(diào)用執(zhí)行。一個(gè)程序使用dll,它只能通過這個(gè)dll的導(dǎo)出函數(shù)/變量訪問其內(nèi)部。在lab windows/cvi下創(chuàng)建dll,有兩種方式導(dǎo)出函數(shù)/變量:頭文件法和導(dǎo)出關(guān)鍵字法。頭文件法使用頭文件確定要輸出的標(biāo)號(hào),頭文件中必須包含要導(dǎo)出標(biāo)號(hào)的聲明;導(dǎo)出關(guān)鍵字法把每一個(gè)要導(dǎo)出的函數(shù)和變量都標(biāo)記一個(gè)關(guān)鍵字,如__cdecl、__stdcall等,根據(jù)不同的編譯器使用不同的導(dǎo)出關(guān)鍵字。在dll中只有被導(dǎo)出的函數(shù)/變量才能被外界所使用,所以只有dll的導(dǎo)出函數(shù)/變量,該dll才具有實(shí)際的使用意義。
dll被調(diào)用時(shí),它有自己的運(yùn)行機(jī)制:每一個(gè)dll都有一個(gè)dllmain主函數(shù),在進(jìn)入和退出dll時(shí),應(yīng)用程序分別調(diào)用這個(gè)函數(shù),它常常被用來執(zhí)行進(jìn)程的初始化和清理工作。因?yàn)樵谠摵瘮?shù)中定義了兩個(gè)事件句柄——dll_process_attach和dll_process_detach。當(dāng)一個(gè)dll被調(diào)用,即它被映射到進(jìn)程的地址空間時(shí),系統(tǒng)觸發(fā)dll_process_attach事件,一般在這部分執(zhí)行特定進(jìn)程的dll初始化工作,如調(diào)用initcvirte()函數(shù)初始化引擎等;當(dāng)應(yīng)用程序結(jié)束dll的調(diào)用時(shí),系統(tǒng)觸發(fā)dll_process_detach事件,一般在這部分進(jìn)行退出dll時(shí)前的資源清理工作,如調(diào)用closecvirte ()釋放被dll所占用的內(nèi)存。另外,cvi還提供了一個(gè)runstatecallback()函數(shù)來對程序的執(zhí)行情況進(jìn)行記錄,使用時(shí)通過該函數(shù)也可以控制程序的執(zhí)行及系統(tǒng)資源分配。
2.2工程中dll的開發(fā)
筆者所參與的測控系統(tǒng)的開發(fā)中, dll開發(fā)采用的是另外一種方式,由于dll本身的不可執(zhí)行性,調(diào)試上沒有可執(zhí)行文件方便,而且工程上需要在導(dǎo)出的dll中包含虛擬儀器軟面板,且保持軟面板對虛擬儀器的控制性,因此,在實(shí)際的開發(fā)中,先編寫cvi用于實(shí)現(xiàn)具體測控功能的可執(zhí)行文件,調(diào)試成功后,把該可執(zhí)行文件改成具有相同功能的dll。改編時(shí),僅僅對源文件(.c文件)的main函數(shù)做一些改變,并在頭文件(.h文件)中輸出,而無需做多的改變即可導(dǎo)出儀器軟面板,這樣在vc++主干程序調(diào)用該dll時(shí)就可以方便的進(jìn)行測控工作。
具體操作上:
?。?)首先編寫滿足測控要求的cvi的可執(zhí)行文件并調(diào)試成功;
(2)在工程文件中打開包含工程主函數(shù)main()的.c文件,向文件中插入dll所必須的dllmain函數(shù)。
?。?)改寫.c文件中的main函數(shù)。修改其函數(shù)名及參數(shù),將其參數(shù)改為windows的實(shí)例句柄hinstance,它指向dll被調(diào)用時(shí)dll被映射到的進(jìn)程的地址空間。另外由于調(diào)用時(shí)要使用儀器軟面板,就必須導(dǎo)出相應(yīng)的.uir函數(shù),因此main中的編譯環(huán)境默認(rèn)的loadpanel函數(shù)要用loadpanelex替代,因?yàn)槭褂胠oadpanel函數(shù)時(shí),用戶界面庫無法找到在.uir文件中定義的但沒有被dll輸出的那些回調(diào)函數(shù),從而使dll在被調(diào)用時(shí)出錯(cuò)。對于loadpanelex,因?yàn)槭褂胏vi編寫dll時(shí),cvi自動(dòng)在工程中生成一個(gè).uir中的回調(diào)函數(shù)列表,dll被調(diào)用時(shí),loadpanelex首先在此列表中進(jìn)行查找,它可以實(shí)現(xiàn)回調(diào)函數(shù)的導(dǎo)出,從而保證在dll中軟面板對虛擬儀器的正常控制。
?。?)將修改后的main函數(shù)的聲明加入到原工程的頭文件。
(5)選擇頭文件導(dǎo)出法,編譯成dll文件。
經(jīng)過改編后原工程就變成了可以由vc++主干程序調(diào)用的dll,而它的所有測試功能都沒有變。事實(shí)證明,因?yàn)檫@種創(chuàng)建dll的方法不需要增加額外的程序進(jìn)行代碼調(diào)試,它比一般的直接創(chuàng)建方法要有效的多。
3 vc++應(yīng)用程序?qū)ll的調(diào)用
3.1 vc程序調(diào)用dll的兩種方式
vc中鏈接dll到應(yīng)用程序中有兩種方式:隱式鏈接和顯式鏈接。隱式鏈接時(shí),使用dll的可執(zhí)行程序鏈接到dll導(dǎo)入庫(.lib文件)中,導(dǎo)入庫中包含了dll中的每個(gè)導(dǎo)出符合和序號(hào)。當(dāng)加載使用dll的可執(zhí)行程序時(shí),操作系統(tǒng)同時(shí)加載dll。為了隱式鏈接dll,可執(zhí)行程序需要從dll提供者獲取以下內(nèi)容:包含導(dǎo)出函數(shù)聲明的頭文件(.h),導(dǎo)入庫(.lib)文件和實(shí)際的dll(.dll)文件。顯示鏈接時(shí),使用dll的可執(zhí)行程序在運(yùn)行時(shí)通過函數(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,與隱式鏈接相比,顯示鏈接較靈活,在這種方式下,我們可以決定什么時(shí)候裝載和卸去dll,以及決定加載哪個(gè)dll,可以節(jié)約系統(tǒng)資源,代碼執(zhí)行效率高。
3.2 vc程序與測試模塊間的通信
在用vc++調(diào)用cvi的dll時(shí),存在著在不同軟件程序間的數(shù)據(jù)傳遞問題,工程中vc++程序是主干,它調(diào)用dll,因此它的變量對dll來說都是透明的、可用的;但是由lab windows/cvi開發(fā)的dll文件生成的導(dǎo)出庫文件(.lib)不包含導(dǎo)出變量,因此dll中的變量值,vc++不能直接獲得。工程中采用創(chuàng)建內(nèi)存映射文件的方法來實(shí)現(xiàn)二者之間的數(shù)據(jù)傳遞。所謂內(nèi)存映射文件是指在內(nèi)存中申請一塊內(nèi)存空間,將一個(gè)文件與這塊空間相,再進(jìn)行內(nèi)存映射,這樣操作文件就有和操作內(nèi)存一樣的效率,數(shù)據(jù)可以通過該映射文件進(jìn)行中轉(zhuǎn)(寫入和讀出),幾個(gè)進(jìn)程可通過操作該映射文件,實(shí)現(xiàn)進(jìn)程間在內(nèi)存一級的高速數(shù)據(jù)交互。
具體方法為:首先在dll中通過api函數(shù)cr-eatefilemapping及mapviewoffile在內(nèi)存中建立一個(gè)文件映射對象并產(chǎn)生它的一個(gè)視,然后通過copymemory將測控?cái)?shù)據(jù)存入
該視中,然后應(yīng)用程序就可使用openfilemapping打開該映射文件并對其進(jìn)行讀寫操作,從而實(shí)現(xiàn)二者間通信。
4 代碼實(shí)例
限于篇幅,文中只給出部分重要的程序代碼。
4.1 cvi中程序代碼
1)對源文件的main函數(shù)進(jìn)行改寫:
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=cr-eatefilemapping((handle)0xffffffff,null,page_readwrite,0,0x300,"mapfile");//建立文件映射對象,mapfile為 映射文件名
……
ipmid=(mid*)mapviewoffile(hvalue,
file_map_all_access,0,0,0);//創(chuàng)建映射對象的一個(gè)視,mid為測控?cái)?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)出儀器軟面板進(jìn)行測試,測控?cái)?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é)合起來進(jìn)行測控系統(tǒng)開發(fā)的方法,根據(jù)兩種開發(fā)工具各自的優(yōu)缺點(diǎn),取vc++對數(shù)據(jù)庫、多媒體等的強(qiáng)大的開發(fā)能力和它廣泛的適用性,結(jié)合labwindows/cvi對測控?cái)?shù)據(jù)強(qiáng)大的分析處理能力和它簡單直觀的儀器軟面板設(shè)計(jì)方法。實(shí)踐證明這種方法是*可行的。