我們知道,不是所有的板卡等硬件都提供了LabVIEW庫(kù)。所以動(dòng)態(tài)庫(kù)(DLL)是我們寫測(cè)控軟件繞不開的一個(gè)話題。本篇推送我們聊一聊什么是動(dòng)態(tài)庫(kù)、它是怎么實(shí)現(xiàn)的、在LabVIEW里我們又如何使用它。
什么是動(dòng)態(tài)庫(kù)? 動(dòng)態(tài)庫(kù)全稱動(dòng)態(tài)鏈接庫(kù)(Dynamic Link Library,DLL),?是一個(gè)包含函數(shù)和數(shù)據(jù)的模塊,它可以被其它應(yīng)用程序或者DLL使用。
動(dòng)態(tài)鏈接庫(kù)是怎么編寫的呢? 簡(jiǎn)單來說就是通過dllexport標(biāo)識(shí)出需要導(dǎo)出的函數(shù)和變量。 我們分別看一下C和C++編寫的動(dòng)態(tài)庫(kù)代碼結(jié)構(gòu)。
C語言編寫的動(dòng)態(tài)鏈接庫(kù)代碼示例:
//CLib.h #ifndef C_LIB_H #define?C_LIB_H //需要導(dǎo)出的函數(shù)按照指定格式聲明 //extern?int?__declspec(dllexport)?exportFunction(type?para,?...); //通過DLL導(dǎo)出add函數(shù) extern int __declspec(dllexport) add(int x,int y); #endif //CLib.c #include?"Clib.h" //add函數(shù)實(shí)現(xiàn) int add( int x, int y ) { return x + y; }
C++語言編寫的動(dòng)態(tài)鏈接庫(kù)代碼示例:
?
//CplusplusLib.h #ifndef LIB_H #define LIB_H //需要導(dǎo)出的函數(shù)按照指定格式聲明 //extern?"C" int?__declspec(dllexport)?exportFunction(type?para,?...); //通過DLL導(dǎo)出add函數(shù) extern "C" int __declspec(dllexport) add(int x, int y); #endif //CplusplusLib.cpp #include "CplusplusLib.h" //add函數(shù)實(shí)現(xiàn) int add( int x, int y ) { return x + y; }與C語言編寫的動(dòng)態(tài)鏈接庫(kù)相比,不同的地方在于extern int “C” __declspec(dllexport) add(int x,int y) 這一導(dǎo)出語句,在C代碼中沒有”C” ,而在C++代碼中多了一個(gè)”C”。 原因是C++編譯器與C編譯器在對(duì)程序進(jìn)行編譯的時(shí)候,對(duì)函數(shù)聲明的編譯會(huì)有所區(qū)別。加上”C”,是為了告訴C++編譯器,使用C編譯器的方式對(duì)這一個(gè)函數(shù)聲明進(jìn)行編譯。這樣,在C程序調(diào)用C++寫的動(dòng)態(tài)鏈接庫(kù)的時(shí)候,不會(huì)發(fā)生因?yàn)閷ふ也坏綄?duì)應(yīng)的函數(shù)名(編譯后的)而發(fā)生Link錯(cuò)誤。
LabVIEW如何調(diào)用動(dòng)態(tài)庫(kù)?
我們以某品牌數(shù)據(jù)采集卡為例,說明一下如何使用動(dòng)態(tài)庫(kù)。 安裝好驅(qū)動(dòng)后,我們可以找到該品牌數(shù)據(jù)采集卡提供的動(dòng)態(tài)庫(kù)函數(shù)和頭文件,D2K-Dask.dll和D2kDask.h。
方法1:直接調(diào)用 所謂直接調(diào)用,就是使用Call Library Function Node調(diào)用。這個(gè)VI位于Connectivity->Librarie&Executables分類下。 在程序框圖里放置Call Library Function Node,雙擊進(jìn)行設(shè)置。在Library name or path中設(shè)置到動(dòng)態(tài)庫(kù)文件,在Function name中選擇需要調(diào)用的函數(shù)(LabVIEW會(huì)自動(dòng)解析出該動(dòng)態(tài)庫(kù)導(dǎo)出的函數(shù)清單)。
例如我們選擇D2K_AI_VReadChannel函數(shù)。這里我們需要找到動(dòng)態(tài)庫(kù)的文檔,按照文檔里提供的函數(shù)說明為CalDl Library Function Node設(shè)置好D2K_AI_VReadChannel函數(shù)的參數(shù)和返回值。
I16 __stdcall D2K_AI_VReadChannel (U16 CardNumber, U16 Channel, F64 *voltage)將Call Library Function設(shè)置對(duì)話框切換到Parameters標(biāo)簽頁,設(shè)置好返回值和參數(shù)。error(return value)、cardNumber和channel都是值傳遞的參數(shù),“Type”選擇Numeric,“Data type”選擇Unsigned 16-bit Interger,“Pass”選擇Value;voltage是指向F64類型數(shù)據(jù)的指針,“Type”選擇Numeric,“Data type”選擇8-byte Double,“Pass”選擇Pointer to Value。
?
?
設(shè)置好之后的Call Library Function Node類似下圖,在左、右側(cè)連接好對(duì)應(yīng)參數(shù)即可調(diào)用D2K_AI_VReadChannel函數(shù)。
這個(gè)設(shè)置和調(diào)用過程,調(diào)用庫(kù)函數(shù)個(gè)數(shù)較少時(shí)還是可以接受的。如果庫(kù)函數(shù)的數(shù)量比較多,挨個(gè)設(shè)置很繁瑣也容易出錯(cuò)。針對(duì)這種情況,LabVIEW有更好的方法,也就是我們要介紹的方法2。
方法2:動(dòng)態(tài)庫(kù)封裝成VI庫(kù) Tools->Import->Shared Library打開Import Shared Library工具。
Step1,打開Import Shared Library,選擇Create VIs for a shared library。
Step2,選擇動(dòng)態(tài)庫(kù)文件和對(duì)應(yīng)的頭文件。注意這里頭文件必須是C/C++規(guī)范的。
Step3,根據(jù)需要設(shè)置頭文件包含路徑和預(yù)處理定義。如果不需要,可以留空。
Step4,LabView自動(dòng)識(shí)別出動(dòng)態(tài)庫(kù)里可以封裝成VI導(dǎo)出的函數(shù)。
例如我們前面設(shè)置的D2K_AI_VReadChannel,這里自動(dòng)識(shí)別出函數(shù)原型來了。
Step5,設(shè)置VI庫(kù)名稱和存放路徑。路徑建議使用默認(rèn)路徑,放置在用戶庫(kù)里。
Step6,設(shè)置出錯(cuò)處理方式。
Step7,設(shè)置各個(gè)導(dǎo)出函數(shù)(VI函數(shù)),一般可選擇使用默認(rèn)設(shè)置。
Step8,LabVIEW給出一個(gè)即將要生成的VI庫(kù)的匯總信息。
Step9,生成中。
Step10,完成VI庫(kù)生成。
勾選“Open the generated library”可以打開生成的VI庫(kù);勾選View the report可以查看有關(guān)所生成庫(kù)的報(bào)表。
打開剛才生成的VI庫(kù),可以看到里面封裝了非常多的庫(kù)函數(shù)。這些庫(kù)函數(shù)如果按照方法1去挨個(gè)設(shè)置,顯然工作量是非常大的。
生成的動(dòng)態(tài)函數(shù)VI庫(kù)怎么使用呢?
在程序框圖里找到User Libraries,里面就有剛才我們生成的D2K-DaskVI庫(kù)。
VIs下面列出了所有庫(kù)函數(shù)對(duì)應(yīng)的VI,把你需要的拖放到程序框圖上,按照輸入輸出類型連接好就可以了。
比如D2K AI V Read Channel.vi,顯示Label、不勾選View as icon,如下圖,輸入輸出非常明了。
以上是C/C++動(dòng)態(tài)鏈接庫(kù)的基本知識(shí)和LabVIEW中如何使用C/C++動(dòng)態(tài)鏈接庫(kù)的方法介紹,希望能夠幫助到大家。
編輯:黃飛
?
評(píng)論
查看更多