新聞中心

EEPW首頁 > 測試測量 > 設(shè)計應(yīng)用 > labview中dll的調(diào)用(包括生成dll)

labview中dll的調(diào)用(包括生成dll)

作者: 時間:2017-01-09 來源:網(wǎng)絡(luò) 收藏
 LabVIEW支持通過調(diào)用DLL文件的方式與其它編程語言混合使用。比如,在實際的工程項目中,用戶可以用C++語言實現(xiàn)軟件的運算部分,并把這些功能構(gòu)建在DLL文件中,然后再使用 LabVIEW編寫程序的界面部分,并通過調(diào)用編寫好的DLL來調(diào)用運算部分的功能。

  LabVIEW 中是通過Call Library Function Node(CLN)節(jié)點來完成DLL文件調(diào)用的。創(chuàng)建一個新的VI,右擊程序框圖,在Functions Palette中依次選中Connectivity——Libraries&Executables工具欄即可找到該節(jié)點(圖1)。

本文引用地址:http://butianyuan.cn/article/201701/337129.htm


圖1 Call Library Function Node

  將節(jié)點放置在程序框圖中,雙擊會出現(xiàn)它的配置對話框,共有四頁。第一頁用于填寫被調(diào)用函數(shù)的信息(圖2)。Library name or path需給出DLL文件名和路徑,操作系統(tǒng)路徑下的DLL文件,直接輸入文件名也可調(diào)用,否則必須輸入全路徑。在這里已經(jīng)給出名字的DLL是被靜態(tài)加載到程序中的,也就是說當(dāng)調(diào)用了這個DLL的VI被裝入內(nèi)存時,DLL同時被裝入內(nèi)存。LabVIEW也可動態(tài)加載DLL,只要勾選上Specify path on diagram的選項即可。選擇了這個選項,在 Library name or path中輸入的內(nèi)容就無效了,取而代之的是CLN 節(jié)點多出一對輸入輸出,用于指明所需要使用的DLL的路徑。這樣,當(dāng)VI被打開時,DLL不會被裝入內(nèi)存,只用程序運行到需要使用這個DLL中的函數(shù)時,才把其裝入內(nèi)存。Function name是需要調(diào)用的函數(shù)的名稱,LabVIEW會把DLL中所有的暴露出來的函數(shù)都列出,用戶只要在下拉框中選取即可。Thread欄用于設(shè)定哪個線程里運行被調(diào)用的函數(shù)。用戶可以通過 CLN 節(jié)點的配置面板來指定被調(diào)用函數(shù)運行所在的線程。CLN 的線程選項非常簡單,只有兩項: Run in UI thread和Run in any thread。LabVIEW的程序框圖上直接可以看出一個 CLN節(jié)點是選用


圖2 填寫被調(diào)用函數(shù)信息

的什么線程。如果Run in UI thread,節(jié)點顏色是橙色的;Run in any thread則是淺黃色的(圖3)。


圖3 CLN不同線程對比

  通常情況下,除非使用的動態(tài)鏈接庫是多線程安全的,CLN 中選擇Run in any thread方式;否則必須選擇Run in UI thread方式。判斷一個動態(tài)鏈接庫是不是多線程安全的,需通過以下方法:如果一個動態(tài)鏈接庫的文檔中沒有明確說明它是多線程安全的,那么就要當(dāng)作是非多線程安全的;在可以看到動態(tài)鏈接庫源代碼的條件下,如果代碼中存在全局變量、靜態(tài)變量或者代碼中看不到有l(wèi)ock一類的操作,那么這個動態(tài)鏈接庫也就肯定不是多線程安全的。

  選擇了Run in any thread方式,LabVIEW會在最方便的線程內(nèi)運行動態(tài)鏈接庫函數(shù),且一般會與調(diào)用它的VI在同一個線程內(nèi)運行。因為LabVIEW是自動多線程的語言,它也很可能會把動態(tài)鏈接庫函數(shù)分配給一個單獨的線程運行。如果程序中存在沒有直接或間接先后關(guān)系的兩個CLN節(jié)點,LabVIEW很可能會同時在不同的線程內(nèi)運行它們所調(diào)用的函數(shù),也許是同一函數(shù)。對于非多線程安全的動態(tài)鏈接庫,這是很危險的操作。很容易引起數(shù)據(jù)混亂,甚至是程序崩潰。

  選擇Run in UI thread方式,因為LabVIEW只有一個界面線程,所以如果所有的CLN設(shè)置都是界面線程,那么就可以保證這些CLN調(diào)用的函數(shù)肯定全部都運行在同一線程下,肯定不會被同時調(diào)用。對于非多線程安全的動態(tài)鏈接庫,這種方式就保證了它的安全。

  讓我們回到配置對話框第一頁,Calling convention用于指明被調(diào)用函數(shù)的調(diào)用約定。這里只支持兩種約定:stdcall和C call。它們之間的區(qū)別在于,stdcall由被調(diào)用者負(fù)責(zé)清理堆棧,C call由調(diào)用者清理堆棧。這個設(shè)置錯誤時,可能會引起LabVIEW崩潰,也就是說如果LabVIEW調(diào)用DLL函數(shù)時出現(xiàn)異常,首先應(yīng)該考慮這個設(shè)置是否正確。(Windows API一般使用的都是stdcall;標(biāo)準(zhǔn)C的庫函數(shù)大多使用C call。如果函數(shù)聲明中有類似__stdcall這樣的關(guān)鍵字,它就是stdcall的。)第二頁是函數(shù)參數(shù)的配置(圖4)。


圖4 配置函數(shù)的參數(shù)

  DLL和LabVIEW之間傳遞參數(shù),最常用的三種數(shù)據(jù)類型是數(shù)值、數(shù)值型數(shù)組和字符串。C語言中經(jīng)常把指針或者數(shù)據(jù)的地址在函數(shù)間傳遞,在32位操作系統(tǒng)中,可以使用int32數(shù)值來表示指針。因此,當(dāng)需要在LabVIEW中傳遞指針數(shù)據(jù)時,可以使用I32或U32數(shù)值類型來表示這個地址類型的數(shù)據(jù)。但是,64位的程序中,數(shù)據(jù)的地址只能使用I64或U64來表示。這樣,如果一個調(diào)用了DLL函數(shù)的VI,并且函數(shù)參數(shù)中有地址型數(shù)據(jù),使用固定數(shù)據(jù)類型的數(shù)值來表示地址,就要準(zhǔn)備兩份代碼。解決方法是使用LabVIEW中的新的數(shù)據(jù)類型Pointer-sized Integer。這個數(shù)據(jù)類型的長度在不同的平臺上會自動使用32位或64位長度。如果在C語言函數(shù)參數(shù)聲明中有const關(guān)鍵字,可以選中Constant選項。布爾類型在DLL函數(shù)和LabVIEW VI之間傳遞沒有專有的數(shù)據(jù)類型,是利用數(shù)值類型來傳遞的。輸入時先把布爾值轉(zhuǎn)變?yōu)閿?shù)值,在傳遞給DLL函數(shù);輸出時再把數(shù)值轉(zhuǎn)為布爾值。對于數(shù)組的傳遞,LabVIEW只支持C數(shù)據(jù)類型中的數(shù)值型數(shù)組,傳遞數(shù)組類型需要注意的的是“Array Format”要選擇“Array Data Pointer”。這個設(shè)置中還有其他兩個選項,帶有“Handle”的參數(shù)類型都是表示LabVIEW定義的特殊類型的。在第三方的DLL中不會使用到數(shù)組參數(shù)作為輸出值時,要記得為輸出的數(shù)組數(shù)開辟空間。開辟數(shù)據(jù)空間的方法有兩種:第一種方法,創(chuàng)建一個長度滿足要求的數(shù)組,作為初始值傳遞給參數(shù),輸出數(shù)的數(shù)據(jù)就會被放置在輸入數(shù)組的所在的內(nèi)存空間內(nèi)。第二種方法是直接在參數(shù)配置面板上進(jìn)行設(shè)置。在Minimum size中寫入一個固定的數(shù)值,LabVIEW就會按此大小為輸出的數(shù)組開辟空間。在 Minimum size 中選擇函數(shù)的其它數(shù)值參數(shù),而不是固定數(shù)值。這樣LabVIEW會按照當(dāng)時被選擇的參數(shù)值的大小來開辟空間。字符串與使用與數(shù)組是非常類似的,實際上在C語言中字符串就是一個I8數(shù)組。

在NI軟件的安裝路徑下打開當(dāng)前使用版本的LabVIEW文件夾,通過 examplesdlldata passingCall NativeCode.llb找到簡單數(shù)據(jù)類型在LabVIEW與C之間的對應(yīng)關(guān)系。部分常見關(guān)系見表1。





表1 數(shù)據(jù)類型對比

  第三頁用于為DLL設(shè)置一些回調(diào)函數(shù),可以使用這些回調(diào)函數(shù)在特定的情形下完成初始化、清理資源等工作(圖5)。


圖5 設(shè)置回調(diào)函數(shù)

  如果為Reserve選擇了一個回調(diào)函數(shù),那么當(dāng)一個新的線程開始調(diào)用這個DLL時,這個回調(diào)函數(shù)首先被調(diào)用??梢岳眠@個函數(shù)為新線程使用到的數(shù)據(jù)做初始化工作。線程在使用完這個DLL之后,它會去調(diào)用Unreserve中指定的回調(diào)函數(shù)。Abort中指定的函數(shù)用于VI非正常結(jié)束時被調(diào)用,也就是讓一個程序在運行完前停止。這些回調(diào)函數(shù)的原型在Prototype for these procedures中列出,必須要由DLL的開發(fā)者按照特定的格式實現(xiàn)。如果使用的DLL不是專為LabVIEW設(shè)計的,一般不會包含這樣的回調(diào)函數(shù)。

  第四頁是錯誤處理方式,用戶可根據(jù)需要選擇相應(yīng)的錯誤檢查級別。

  另外還需要注意的是,C語言中的struct在LabVIEW中可以使用cluster來表示,但有時需要作出相應(yīng)的調(diào)整。這是因為在C語言中,struct的字節(jié)對齊是可以進(jìn)行設(shè)置的,這就決定了其各元素的存放地址的可變性。C語言中的對字節(jié)對齊數(shù)可通過#pragma pack指令或在工程屬性中進(jìn)行指定。而在LabVIEW的cluster中,所有元素只能是1字節(jié)對齊的,所以如果要和C語言中非1字節(jié)對齊的struct對應(yīng),需要做出一些調(diào)整。比如,對于C語言中2字節(jié)對齊的struct,第一個元素如果是I8型的,在LabVIEW的cluster中第一個元素對應(yīng)不變,但不能緊挨著放第二個元素,必須留一個無意義的空位。C語言的struct其實也是如此,只不過沒有表現(xiàn)出來。所以為了方便,如果自己用C語言生成DLL文件供LabVIEW調(diào)用最好將struct都設(shè)為1字節(jié)對齊。C語言的struct中可以嵌套數(shù)組,但是這和LabVIEW中含有數(shù)組元素的cluster是不一樣的,LabVIEW中需要將數(shù)組中的元素都拆開放入cluster中。

  如果C語言的struct中含有一個指針,LabVIEW中的cluster只能用一個U32數(shù)值(32位系統(tǒng)上,64位系統(tǒng)上使用U64)來表示指針的地址,而不能將指針?biāo)赶虻膬?nèi)容放到Cluster中去。如果聲明的是指向struct的指針,才能在LabVIEW中使用cluster與之對應(yīng)。CLN節(jié)點的配置面板中,沒有一個專門命名的“struct”或者“cluster”參數(shù)類型,應(yīng)選擇“Adapt to Type”就可以了。如果參數(shù)的類型就是結(jié)構(gòu)而非指針,考慮到C函數(shù)參數(shù)的壓棧順序,把一個結(jié)構(gòu)體作為參數(shù)傳給函數(shù),相當(dāng)于把結(jié)構(gòu)中每個元素分別作為參數(shù)傳遞給函數(shù)。圖6為C語言中struct和LabVIEW中cluster的部分匹配圖。


圖6 struct和cluster匹配

LabVIEW打包DLL文件

我們接下來學(xué)習(xí)如何使用LabVIEW來打包一個DLL文件。

  首先我們編寫一個名為Scale.vi的程序,功能很簡單就是對輸入的數(shù)據(jù)乘上10,然后再輸出(圖7)。


圖7 scale.vi

  必須在任務(wù)管理器中才能生成.dll文件。所以我們首先建立一個project,過程如下:

點擊File>>New Project:


圖8 生成新項目

  接著彈出是否將該VI添加到新項目的對話框:


圖9 是否添加VI到新建項目

  選擇Add,生成新的項目管理器,將其保存在需要的路徑下:


圖10 項目管理器

  右鍵單擊項目瀏覽器窗口中的Build Specifications,在快捷菜單中選擇New>>Shared Library(DLL),彈出對DLL文件進(jìn)行設(shè)置的對話框。點擊Category>>Information,根據(jù)自己需求修改Build specification name和Target filename:


圖11 Information頁面

  點擊Source Files>>Project Files>> Scale.vi>> ,彈出對話框,直接用默認(rèn)值,點擊OK:


圖12 Define VI Prototype


上一頁 1 2 下一頁

關(guān)鍵詞: LabVIEWDLL指

評論


技術(shù)專區(qū)

關(guān)閉