動態鏈結庫在LabVIEW中的高階應用

2021-08-15 17:56:34 字數 4107 閱讀 6221

動態鏈結庫在labview中的高階應用

摘 要:labview中的提供了呼叫共享庫函式的介面,但是一些現成的函式庫卻因為介面引數型別不同而不能在labview中使用。利用重新編寫動態鏈結庫的方法可以建立舊函式庫與labview聯絡的通道,提高現有資源的利用率。本文以sdk2000影象採集卡為例,介紹具體的實現過程。

關鍵字:labview;動態鏈結庫;clf節點

1. 引言

實驗室虛擬儀器工作平台是美國國家儀器公司研製的一種通用程式開發系統,以其強大的資料採集、資料處理、資料分析和儀器控制功能在現代測控領域中得到了廣泛的應用。ni公司在推出labview語言同時,也推出了一系列的資料採集卡,但實際應用中往往會用到第三方廠家生產daq卡,在這種情況下就需要使用labview提供的外部程式介面。

labview的「呼叫函式庫節點(clf節點)」提供了呼叫標準函式和使用者自定義函式的通用方法,對於labview不支援的硬體裝置大部分採用這種方法進行驅動。但是clf節點也存在不足,使用中遇到最多的問題是引數型別不匹配。使用重寫動態鏈結庫的方法,一方面可以相容舊函式庫的引數型別,另一方發面可以獲得labview提供的高階函式庫應用。以下以sdk2000影象採集卡為例,介紹重寫函式庫的基本原理和程式編寫過程。

2. 實現方案及方案論證

sdk2000影象採集卡提供的visual c++ ide 程式開發包包含了外部程式呼叫的共享函式庫,但是有些函式不能直接用clf節點進行呼叫。主要有兩個原因:庫函式的引數型別與labview不相容;圖形化語言對於一些底層操作不易實現。sdk2000影象採集卡提供的庫函式含有labview不支援的資料型別,並且很多函式涉及到一些底層操作,如檔案讀取和記憶體管理。為了正確呼叫函式並返回有效資料,解決這兩個問題是關鍵。

labview僅提供最基本的資料型別,雖然可以在clf節點引數設定中選擇「adapt totype」,但只能夠傳遞labview內部使用的引數型別而已,而共享庫函式使用上百種非標準資料型別。引數型別不匹配可分為兩種情況:

● 非標準資料型別定義。很多程式和函式用到一些非標準的型別定義,例如它們常常用char、short和long的型別定義代替windows api使用的byte、word和dword。這種情況下要正確呼叫這些程式和函式,必須找到這些引數在labview中同等的資料型別。

● 以結構或者類作為引數。一些程式和函式使用結構或者類作為引數,但是labview並不能夠識別這些引數的資料結構。為了正確呼叫這些庫函式,labview提供了兩種解決辦法:使用cin節點或者重寫函式庫對這些函式進行重新封裝,使這些函式的輸入輸出引數能夠符合labview的標準。

sdk2000提供的共享函式庫使用了很多labview不支援的引數型別,如rect、videostreaminfo等。為了正確呼叫這些函式,必須用cin節點或者重寫函式庫的方法對這些函式進行重新封裝。相對而言,重新編寫動態鏈結庫方法比使用cin節點更為常用。因為cin**直接嵌入到vi程式**裡,對於程式設計器的限制比較高,所以一般不採用cin節點。

重新編寫動態鏈結庫的另乙個原因,是為了獲得labview提供的高階函式庫應用。labview提供了在**開發環境下的高階函式庫,這些函式是針對於labview使用的資料型別,如下面所介紹的numericarrayresize()函式。numericarrayresize()函式用於動態改變陣列的大小,不過只適合於labview使用的陣列結構。labview高階函式庫還包含了一些底層操作,如檔案讀寫與記憶體分配等等,不存在引數型別不同和底層操作困難的問題。

3. 軟體程式設計

由於需要重寫的函式比較多,這裡僅以重寫儲存dib影象資料函式為例,說明重寫函式庫的編寫過程。新函式getdib()對原函式dsstream_getcurrentdib()進行了封裝,其作用是向原函式傳遞有效引數並返回labview能識別的資料。使用的程式設計環境為visual c++6.0。

第一步:分析目標函式的引數型別

sdk2000開發包中對獲得當前影象的dib資料函式的宣告為:

hresult dsstream_getcurrentdib(int icardid,byte* pbuffer,long* psize)

pbuffer指向預分配的記憶體,值為null時,psize得到儲存影象需要的記憶體大小,若pbuffer不為null,函式將dib影象資料儲存到從pbuffer開始,長度為(*psize)的記憶體區域。clf節點不能直接呼叫該函式,因為labview程式設計環境下沒有提供記憶體管理機制,並且clf節點不能把指向預分配記憶體的指標傳遞給該函式,所以必須對這個函式進行重新封裝。

影象的dib資料是非數字型的資料,為了返回labview能夠識別的資料,可以選擇字串或者單位元組陣列作為資料的載體,但是由於資料中包含了十進位制的0,所以只能用單位元組陣列作為載體,並且為了能夠動態改變陣列的大小,必須以陣列的控制代碼作為傳遞引數。因為在labview提供的高階函式庫中,所有改變陣列、字串大小的函式都是針對於控制代碼進行的。

typedef struct

{ int32 dimsize;

uint8 elt[1];

} td1;//td1的資料結構能被labview和新鏈結庫識別

typedef td1 **td1hdl;

extern "c" __declspec(dllexport) long getdib(td1hdl bitmapinfo)//bitmapinfo為陣列的控制代碼

{ long pp=0;

hr=dsstream_getcurrentdib(m_icardid, null, &pp);//得到儲存影象需要的記憶體大小

if (numericarrayresize(ub,1l,(uhandle*)&bitmapinfo,pp))//改變陣列物理大小

return 0;

(*bitmapinfo)->dimsize = pp;//改變陣列大小的標誌

byte* lpdst; // 指向快取dib影象的指標

lpdst = (*bitmapinfo)->elt;

hr=dsstream_getcurrentdib(m_icardid, lpdst, &pp);//將當前影象的dib資料儲存到記憶體中

bitmapinfo* pinfo = (bitmapinfo*)lpdst;//位**件頭指標

return pinfo->bmiheader.bisize;//返回位圖資訊頭的資料長度

}編寫過程的幾點說明:

● 為了正確使用labview中的資料型別,必須在mysdk2000.cpp中手工加上#include 「extcode.h」的宣告。標頭檔案」extcode.h」中定義了cin和外部子程式所用到的基本資料型別和許多函式等,用以解決某些常量和資料型別與系統標頭檔案的衝突。

● 為了能夠在vc中呼叫labview的函式庫,必須把cintools目錄下labview.lib包含在工程裡。使用numericarrayresize()函式用以動態改變陣列的長度,它的功能和win32函式localalloc()具有相似的功能。它的函式宣告如下:

mgerr numericarrayresize(int32 typecode, int32 numdims,

uhandle *datahp,int32 totalnewsize);

● 如果記憶體分配失敗,函式返回錯誤**。如果成功,還須修改陣列結構中的dimsize,因為此函式不能自動修改此值。

其它**的編寫類似於vc環境下的開發。**完成後,構件並產生最終的目標檔案mysdk2000.dll。

配置clf節點的各項引數。第乙個選項為函式庫檔名和路徑,選擇剛才編譯的檔案mysdk2000.dll;第二個選項為函式名,選擇getdib;第三項設定返回和傳遞引數。具體設定如下表:

其它選項保持預設設定。程式框圖如下:

為了弄清楚clf執行時傳遞引數和返回引數的原型,可以在clf節點上右鍵彈出選單中選擇「creat.c file…」,然後在文字程式設計環境下察看它的引數原型。這些引數原型其實就是labview使用到的資料結構,如上面說看到的陣列結構td1,td1為labview一維陣列的資料結構。

4. 結論

通過對原有函式的封裝,函式將影象卡採集的dib資料以陣列形式返回給labview,labview將對這些資料進行進一步的處理,如二值化、邊緣分析等等。實踐證明,通過重寫動態鏈結庫的方法,第三方daq裝置可以更協調地使用於labview開發環境中。

動態鏈結庫 靜態鏈結庫

包含標頭檔案和庫 idir 指定編譯查詢標頭檔案的目錄,常用於查詢第三方的庫的標頭檔案,例 gcc test.c i.inc o test。ldir 指定鏈結時查詢lib的目錄,常用於查詢第三方庫。llibrary 指定額外鏈結的lib庫 巨集定義 dmacro 以字串 1 預設值 定義 macro...

靜態鏈結庫 動態鏈結庫

庫是寫好的現有的,成熟的,可以復用的 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種 靜態庫 a lib 和動態庫 so dll windows上對應的是.lib dll ...

靜態鏈結庫,動態鏈結庫

關於靜態鏈結庫,參考如下博文 當你完成了 開發,想把這個 給別人用,但是又不希望別人看到原始碼,就要給別人乙個庫和標頭檔案,庫和標頭檔案是配合的,缺一不可。或者過程相反,你從別人那裡拿到乙個庫和標頭檔案來使用。那麼如何編譯生成乙個庫給他人,如何使用從他人那裡拿到的庫呢?範例1 我們想把linuxfr...