在INTERNET/INTRANET網路通訊技術的迅猛發展的今天,分布式異構整合應用系統的開發和使用是必然發展方向;JAVA具有穩定、可靠、跨平台等優點,利用其開發分散式運算系統,是必然的趨勢。同時,
JAVA開發必須繼承並整合現存的系統,因此,JAVA與各現存的軟體系統通訊現在已經提上了議程。 MATLAB是Mathworks公司推出的針對數值計算的互動式軟體,具有強大的數值分析、矩陣運算、訊號處理和圖形顯示功能;MATLAB以其強大的資料處理能力和豐富的工具箱使得他的編程極為簡單,可大幅縮短應用程式開發週期,提高編程效率。因而JAVA通過VC++實現MATLAB的圖形處理和顯示是提高效率的一種可行策略。最終實現JAVA、MATLAB通訊必須解決兩方面的問題:一是JAVA與VC++的通訊;二是VC++與MATLAB的通訊。 本系統(是分布式網路多代理系統中的一Proxy 伺服器——人工神經網路代理程式伺服器)的功能實現是:從JBUILDER開發環境的JAVA程式通過調用包含MATLAB圖形處理和顯示功能DLL,實現映像顯示。其中VC需要MATLAB的“title.m、xlabel.m、ylabel.m”三個檔案和為實現圖形處理顯示編寫的檔案“errorpicture.m”。系統的開發環境是:WindowXP作業系統、VisualC++6.0和JBUILDER6.0開發工具、MATLAB6.5軟體。 1 實現JAVA與VC通訊方法簡介 JAVA與VC的互動可以通過各自單獨啟動並執行程式讀寫約定的格式的檔案來交流,但是通訊的即時性不能保證;可以利用CORBA機制,通過定義IDL介面的客戶機/伺服器(CLIENT/SERVER)的形式通訊,這加大了系統簡易功能實現的複雜化;還可以通過JNI(Java Native Interface)或RMI(Remote Method Invocation)等方法實現。 在微軟的作業系統上,實現本機程式之間的通訊應用JNI機制較方便快捷、穩定可靠,並能實現即時通訊。本樣本系統的實現就使用了此機制。 1.1 實現JAVA與VC++(DLL)互連 首先在JBUILDER中建立一工程,如:MASS,使用MASSFrame為架構(Frame)的類名。 系統為了使用VC中實現的MATLAB圖形處理的DLL,需在JAVA檔案的class MASSFrame中,添加如下一些代碼: public native void showPicture(); //實現調用的DLL中函數申明 static { System.loadLibrary ("showpicture"); //使用DLL檔案,其名稱是“showpicture.dll” } void jBShowPicture_actionPerformed(ActionEvent e) { showPicture(); //JAVA程式對DLL中函數的使用 } 1.2 系統回合設定與編譯 須對使用DLL中MATLAB函數的JAVA檔案編譯屬性進行設定,在JBUILDER工具中的Project視圖地區找到class MASSFrame.java(各開發人員確定的檔案名稱可能不同)的檔案,選中後按下滑鼠右鍵,在出現的菜單中選擇“Properties”項,接著按照“Build->RMI/JNI->Generate JNI header file”找到“Generate JNI header file”項目,選定。編譯該檔案,可得相應的h檔案。本系統產生“mass_ MASSFrame.h”,其中調用的函數為:“JNIEXPORT void JNICALL Java_mass_MASSFrame_showPicture (JNIEnv *, jobject); ”。 如果僅使用SUN公司的JDK來實現,須用javah.exe將javac.exe編譯產生的class檔案去產生對應的h檔案,接著修改h檔案,即將檔案所在的包層次,在被調用的函數名上體現出來,也就是“JNIEXPORT void JNICALL Java_MASSFrame_showPicture (JNIEnv *, jobject); ”修改為上面的調用函數名。 1.3 JAVA應用系統運行 將VC產生的DLL檔案拷到JBUILDER當前運行程式的目錄下,執行程式,就實現JAVA系統和MATLAB的通訊。本樣本系統的DLL是“showpicture.dll” (即下面的“實現VC、MATLAB通訊方法簡介”所產生的)。其運行結果顯示圖1: 圖1 JAVA調用DLL的映像顯示 2 實現VC、MATLAB通訊方法簡介 MATLAB提供了許多方法與VC程式的通訊:MATLAB引擎(ENGINE)模式,採用了客戶機/伺服器(CLIENT/SERVER)的計算形式,通過MATLAB應用程式介面(API)中有關函數,在VC環境中調用MATLAB函數,但此種方法需要MATLAB環境後台支援,因此系統必須安裝MATLAB;MATLAB本身提供的MCC工具編譯,編譯m檔案產生VC++或c語言,直接在VC中使用;MATLAB的MEX工具將m檔案編譯成DLL,供VC調用。。。。。。 MATLAB現具有的MATLAB Add—in(其封裝了MCC、MEX)更方便了第二、三種方法的應用,現本系統的實現就是以第三種為基礎的。 2.1 MATLAB與VC實現互連 為了在開發時實現對MATLAB的具體功能的調用,應首先在作業系統中安裝MATLAB工具軟體,之後並運行此工具軟體,依次執行“mex –setup;mbuild –setup;cd(prefdir); mccsavepath;”命令。之後運行VC開發工具,從VC++菜單中依次開啟“Tools->Customize->Add-ins and Macro Files”,選中MATLAB Add—in宏,可以看到工具列中多了一個 。現在VC就可以利用它來得到m檔案所對應的c、c++檔案。 2.2 開發工具VC運行環境設定 開發時,須對VC的開發環境變數進行設定。通過“Tools->Options->Directories”找到的“Directories”項中添加環境變數。 添加標頭檔和庫檔案搜尋路徑有(本電腦的檔案搜尋路徑為): F:/MATLAB6P5/EXTERN/INCLUDE F:/MATLAB6P5/EXTERN/INCLUDE/CPP 同時將MATLAB的連結庫添加到VC中。從“Tools->Options->Directories”中“Show directories for:”下拉框裡選擇“Library files”,然後再在“Directories”項中添加環境變數。 F:/MATLAB6P5/EXTERN/LIB F:/MATLAB6P5/EXTERN/LIB/WIN32 F:/MATLAB6P5/EXTERN/LIB/WIN32/MICROSOFT/MSVC60 上述為VC編譯MATLAB的m檔案產生C代碼的環境。同時為了編譯JNI的h檔案,還須通過菜單Tools.和Project添加如下標頭檔和庫檔案搜尋路徑: D:/JBUILDER6/JDK1.3.1/INCLUDE D:/JBUILDER6/JDK1.3.1/INCLUDE/WIN32 2.4 VC產生DLL 本系統首先用VC建立“MATLAB Project Wizard”項中名稱為showpicture的Project,其中Project的選項結果如2所示: 圖2 建立工程選項結果 將1.2中產生的mass_ MASSFrame.h檔案拷貝到系統目錄下,並添加到VC的“FileView”中“HeadFiles”裡面。 在VC中為了對JAVA程式提供可調用的函數,須在“showpicture.c”檔案中添加: #include " mass_ MASSFrame.h" //dll匯出的JAVA調用函數的具體實現部分 JNIEXPORT void JNICALL Java_mass_MASSFrame_showPicture (JNIEnv *en, jobject ob) { showpictureInitialize();//初始化 mlfErrorpicture();//映像顯示 mlfHGWaitForFiguresToDie();//關閉顯示相關資源 } “F7”編譯器,於是便得到“showpicture.dll”。 2.3 脫離MATLAB環境啟動並執行支援檔案 為了在沒有安裝MATLAB應用軟體的環境下,能夠使用其功能的DLL,須在運行此DLL的目錄中添加一些檔案,而這些檔案可以通過工具列中的“MATLAB Add-in Packager”獲得。按照此工具預設的配置運行,得到一個zip壓縮檔,使用時,將其解壓到DLL檔案所在的目錄中,DLL就能脫離MATLAB環境使用。 3 結論 採用JAVA系統在對外服務時,利用MATLAB完成軟體核心演算法設計和圖形處理、顯示,很大程度上降低了編程難度和工作量, 縮短開發週期,並提高了軟體的可靠性。基於VC++6.0實現JAVA和MATLAB的通訊——利用VC編譯器調用包含MATLAB處理功能的動態串連庫實現脫離MATLAB環境下運行實現JAVA和MATLAB二者的緊密結合,更極大拓展了MATLAB的應用範圍,並同時也深化了JAVA和MATLAB的應用能力。 附註:errorpicture.m檔案的內容如下: function errorpicture() s='NN/訓練誤差結果顯示.txt'; fid=fopen(s,'r'); while (feof(fid))~=true [x,n]=fscanf(fid,'%12f'); end; if(n>1) t=1:1*100:n*100; plot(t,x); ylabel('誤差絕對值'); xlabel('訓練次數(次)'); title('人工神經網路訓練誤差結果顯示圖'); grid; end; fclose(fid); |