最近參加的培訓有點多,需要看的東西有點多,沒時間更新第二篇博文,很抱歉。
-------------------------------------------------------------------------------------------------------------------
首先我們回顧下前一篇博文所做的工作:
1.在Panel界面新建了一個用於用戶登入的Panel界面。
2.在System Variables中創建了用於后續CAPL編程的變量,並在Panel界面中實現了變量與Panel控件之間的連接。
最后我們要做的就是編寫CAPL腳本,實現登入功能。
(一)CAPL介紹
CAPL語言是一種類C的面向對象的語言,主要用於Vector公司開發的工具鏈。
CAPL最重要的一個特征是事件觸發,這一特點在我看來十分重要,對向我一樣的初學者可能第一次看到CAPL腳本有點奇怪--為什么沒有main函數?不是類C嗎?
第一次看到CAPL,我以為是像python一樣一行一行向下執行的,但發現只有很多類似於函數的代碼塊,在這些代碼塊外部並沒有代碼啊?這時候我們就要記住CAPL是事件觸發的。個人認為可能是因為CAPL是用於汽車總線的仿真,測試的,而這種應用場景常常需要對出現特定的事件做出相應的處理,所以vector公司采取了這種獨特的方式(以上是個人的猜想,純屬胡扯)。
(二)代碼
- /*@!Encoding:936*/
- includes
- {
- //#include "string.h"
- }
- variables
- {
- char buf[10];
- char buf2[10];
- char user[10][2][10]; //賬號,密碼最多為9位字符,最多存儲10個人的賬號密碼
- int i;
- int status;
- int IO;
- Timer t1;
- char Panel2[10];
- }
- on start
- {
- setTimer(t1,10000);
- }
- on timer t1
- {
- if(IO==0)
- {
- stop();
- }
- }
- on sysvar Login::Login
- {
- strncpy(user[0][0],"amber",10); //輸入賬號密碼的數據
- strncpy(user[0][1],"1234",10);
- strncpy(user[1][0],"baby",10);
- strncpy(user[1][1],"2345",10);
- strncpy(user[2][0],"carry",10);
- strncpy(user[2][1],"6789",10);
- sysGetVariableString(sysvar::Login::ID, buf, elcount(buf)); //得到ID和Password
- sysGetVariableString(sysvar::Login::Password, buf2, elcount(buf2));
- status = 0; //確定賬號密碼是否正確
- for(i=0;i<10;i++)
- {
- if((!strncmp(user[i][0],buf,10))&&(!strncmp(user[i][1],buf2,10)))
- {
- status = 1;
- break;
- }
- }
- if(status==1)
- {
- write("OK"); //TRUE
- IO = 1;
- }
- if(status==0)
- {
- write("ERROR"); //ERROR
- SetControlForeColor("", "", MakeRGB(255,0,0));
- stop();
- }
- }
因為復制粘貼的緣故,行縮進消失了,嫌麻煩就不改了,將就着看吧
首先在第一次打開時,會出現如下界面
學過C語言的都知道第一個大括號中的內容是頭文件,這里由於代碼量較小,無須在這里編寫任何代碼,細心的同學可能發現我include了"string.h",然后又注釋掉了,注意這里和C存在極大的區別,在C中能用的頭文件,並不一定能在CAPL中使用,這給我們的學習帶來了極大的不便,希望哪位大神用CAPL實現下這些常用的頭文件吧!!!所以切記不要想當然把CAPL當成C語言的用。第二個大括號中寫的就是變量,由於后面都是基於事件的代碼塊,沒有定義變量的地方,所以變量的定義就挪到了最前面,需要有些奇怪,但不得不說這樣的設計也是非常便利的。畢竟我們寫C的時候把變量寫在前面也非常的利於我們的閱讀。
在前面反復強調CAPL是事件觸發的,那么怎么寫呢?
這段代碼及其簡單,但卻是在我們編程過程中時常用到的兩個重要函數
on start顧名思義是在CAPL開始運行時執行,但這里還有另一個on prestart 這兩者之間也存在一定區別,這里不做過多介紹,有需要去看具體的help文檔就可以了。
setTimer這個是個極其重要的函數,可以說無論是在那個CAPL的編程中,這個函數的使用都是極為廣泛的。這個函數的作用是設置一個計時器,第一個實參是作為計時器的變量名,第二個是時間,時間單位為ms。這里很奇怪,help文檔中明明demo顯示單位是s的,但是實驗證明單位是ms,不知道是什么緣故。后面弄清楚后會專門出個博文。
這里的stop()是停止CANoe運行的函數,了解即可,不必關系我這里這么寫的邏輯。
這是核心的代碼,寫了用戶的登入信息和如何對用戶的輸入信息進行核對,確認是否正確。
on sysvar Login::Login是極重要的代碼,代表當系統變量發生變化時,執行指定的代碼塊,使用系統變量的話建議直接從系統變量欄中拖取,這樣不容易出現錯誤,畢竟當系統變量多的時候誰都記不住那么多的變量名(哪怕已經取了很清楚的名字了)。
strncpy()函數用法如下:
簡單來說就是,第一個實參是目標變量,第二個實參是要復制的字符串,第三個變量是字符串長度,注意理論上來說,最大能復制的字符串應該是len-1,因為在字符串的最后需要'/0'作為字符串的結束符號,但是在實驗過程中就算我字符串用了len長度仍然成功復制了,沒有出錯,就很奇怪,所以后續會研究下,要是有結果,也會和前一個問題一樣重新開一個博文。
在這里strncpy()起到的作用就是將用戶的信息存儲在一個三維數組中。
要完成比對的過程我們還需要獲取用戶的輸入信息,這就用到了sysGetVariableString()函數,函數用法如下:
我們在這里采用第二種形式,我們將Panel界面中輸入的信息獲取,並存儲到一個buffer中。
下面代碼較為簡單,就是個比對,和C語言幾乎一模一樣,這里不做敘述了。
stop()函數就是終止CANoe運行的函數。其他的IO,status就是我做的一些flag,相信大家也能理解。
這里我大致說下邏輯,以便大家更好的理解:CANoe在加載了這個配置文件后,會有一個Panel界面,當用戶點擊運行開始使用CANoe后,需要在一定時間內完成登入,否則CAPL會自動關閉CANoe。
謝謝!