為了說明狀態機、動態調用的作用和動態調用的注意事項,設計如下小程序
首先從Excel文件中讀取100個數,面板有兩個按鈕,一個可以將這100個數求和,另一個將每個數加1. 之所以設計這個看起來沒什么用的程序,是因為邏輯上以及架構上和最近做的一個實際項目很接近,只是功能簡化了很多,此外還有以下幾個原因
- 動態調用VI的目的是為了優化內存,不過小程序不容易看出內存優化的狀況。初始化時讀取Excel,引入了其他程序,可以從Windows任務管理器里觀察內存的占用情況
- 對讀取Excel的VI進行動態調用,可以表明附加文件(如本文中的Excel)路徑和動態VI路徑的獲取方式,雖然它們在Windows中的同一個文件夾下,但獲取路徑的過程有細節上的區別。本文主要為了表明這一點。
- 讀取Excel的VI采用如圖1所示的調用Excel屬性節點和方法節點的方式,LabVIEW有一套和Excel交互數據的庫,是收費的,外企很重視授權問題,我用的LabVIEW是授權的,在沒有購買這個庫的情況下還是采用比較原始的方式操作Excel。個人學習的話無所謂,NI官方為了推廣似乎也不是很重視版權,不過企業使用還是不要帶來不必要的麻煩。
圖1
進入正題。寫好圖1的讀取Excel的VI后,建立兩個項目,兩個主VI分別用直接調用和動態調用的方式來調用它,構建一個簡單的狀態機,再加上一點簡單的算法就可以了。待讀取的Excel就是A1到J10單元格分別寫下1到100. 具體見圖2和圖3. 圖2中獲取應用程序的類型是為了區分是以VI運行還是以exe運行。以exe運行時路徑會多出一層虛擬文件夾,后面會有更詳細的說明
圖2
圖3
因為是直接調用,所以當把Direct Call(即主VI)添加到項目中時,被直接調用的子VI自動出現在了“依賴性”目錄中,Build完成后,把Excel文件拷到exe相同的目錄,如圖4
圖4
生成exe也正常運行,不過可以看到如圖5所示,在沒有打開Excel文件的情況下,Excel進程正在運行。直到關閉exe應用程序,Excel進程才會自動結束。
而且直接調用時所有子VI也都被加載到內存中,如果是很多子VI組成的大型程序,會占用大量內存。尤其是當VI后期不再被調用時,這些內存也無法釋放。
圖5
下面來看動態調用。動態調用只在VI被調用時才加載進內存,調用完成后釋放相應內存。
首先編寫如圖6的子VI,它被主VI直接調用,又作為主調函數動態地調用“Read Excel.vi”
圖6
然后主VI調用上面子VI時,需要傳遞的實參就是“Read Excel.vi”(即需要被動態調用的VI)的路徑,以及要讀取的Excel文件的路徑。
這里VI路徑這一項容易出問題,因為VI和Excel文件在同一目錄,所以很自然的會寫成如圖7這樣,用同一個根目錄組合出兩個路徑。(只截圖初始化部分,其余部分不變)
圖7
上面的VI運行起來完全可以實現我們需要的效果,如果點擊白色運行箭頭的過程中一直觀察Windows任務管理器,可以看到Excel進程出現了1秒鍾左右就又消失了,然后程序的功能也完全沒有問題。於是開始生成exe。
創建的過程就沒有直接調用那么順利了,如圖8所示,因為“Read Excel.vi”沒有被直接調用,所以不會出現在“依賴性”里面,也就沒有出現在這個工程里。顯然無法繼續Build
圖8
這個問題解決起來比較容易,既然“Read Excel.vi”沒有自動進入工程,我們就手動把它添加進來,然后Build時放到“總是包含”里面,如圖9,就可以生成exe了
圖9
Build完運行exe,結果如圖10,找不到“Read Excel.vi”。而且通過第三條“動態VI路徑”可以看出軟件希望找到這個VI的完整路徑並不存在,自然是找不到的。讀不到Excel,后面的計算等功能自然就不能用了
圖10
如果改成圖11這種路徑設置的方式,即只拆分一次路徑再組合成動態VI的路徑。exe運行界面第三個路徑同樣顯示了系統尋找動態VI的路徑,是在“動態調用.exe”這個虛擬文件夾,Build過程中把動態VI包含在了“總是包含”里,就是為了實現這個。
運行效果如圖12,沒有錯誤且可以實現功能
圖11
圖12
總結一下本文要表述的要點
- 動態VI調用使程序變得更復雜,但是對於比較耗資源且不頻繁調用的VI,動態調用對優化內存很有幫助。本程序的讀取Excel只在初始化時調用一次,讀取到數據后不再被調用,且被調用時占用較多系統資源,是很適合使用動態調用的
- 附加文件(如本文的Excel文件)的路徑需要區分應用程序類型是VI(Deployment System)還是exe(Run Time System)。以exe運行時,因為多了一層虛擬文件夾,因此需要多拆分一次路徑
- 動態VI的路徑不用區分應用程序類型,都是拆分一次。對於以VI運行,拆分一次之后就是VI所在的文件夾;對於以exe運行,拆分一次之后是虛擬文件夾,只要Build時把動態VI添加到“總是包含”即可。
本程序設計一個動態調用讀取Excel,就是同時涉及到了上面2,3兩條,可以作對比參考。
最后提一下,如果程序是圖7那種不正確的方式,只是會導致程序在沒有動態VI的地方尋找它,我們只要把這個VI復制到程序希望找到它的位置,程序依然可以正常運行,如圖13,即使客戶機沒有安裝LabVIEW不能識別VI文件也可以。
圖13