chb請注意:改文有一定的參考價值,實際編程實現就未必一定用這個方法(僅僅做參考用)
[ 作者:佚名 轉貼自:中國學術交流園地]
系統實現:從JAVA程序傳遞噪聲標準差和兩個數據給MATLAB,即給其實現具體的數據計算功能的DLL(通過VC++生成DLL),產生高斯分布的白噪聲數據。其中VC需要MATLAB軟件自帶的"normrnd.m、rndcheck.m"兩個文件和產生白噪聲的文件"noise.m"。開發環境是:Window2000操作系統、VisualC++6.0和JBUILDER6.0開發工具、MATLAB6.5軟件。
要實現JAVA、MATLAB通信必須解決兩方面的問題:一是JAVA與VC++的通信;二是VC++與MATLAB的通信。~..~
1 實現JAVA與VC通信方法簡介
JAVA與VC的交互,可以通過各自單獨運行的程序讀寫約定的格式的文件來完成,但是通信的實時性不能保證;可以利用CORBA機制,通過定義IDL接口的客戶機/服務器(CLIENT/SERVER)的形式通訊;還可以通過JNI(Java Native Interface)或RMI(Remote Method Invocation)等方法實現。
在微軟的操作系統上,實現本機程序的通信應用JNI機制較方便快捷、穩定可靠,并能實現實時通信。本示例系統的實現就使用了此機制。
1.1 實現JAVA與VC++(DLL)互連
在JUBILDER6開發環境中,系統先生成NNSD的Project,其框架類名為Frame1。
系統為了使用VC實現的DLL,在Frame1.java文件中調用VC中函數處添加如下一些代碼:
public native void makeNoise(float m,int n);
//實現調用的DLL中函數申明
static


{
System.loadLibrary ("makenoise");
//使用DLL文件,其名稱是"makenoise.dll"
}
void jButton1_actionPerformed(ActionEvent e)
//框架通過按鈕消息實現DLL的調用


{
int n=160;//白噪聲數據量
float m=1.0;//白噪聲方差平方
makeNoise(m,n);
//JAVA程序對DLL中函數的使用
}

1.2 系統運行設置與編譯
使用JBUILDER開發時,須對使用DLL中函數的JAVA文件編譯屬性進行設置。本系統在JBUILDER工具中的Project視圖區域找到Frame1.java(各開發者確定的文件名可能不同)的文件,選中后按下鼠標右鍵,在出現的菜單中選擇"Properties"項,接著將"Build->RMI/JNI->Generate JNI header file"找到的項目選定。最后編譯該文件,可得相應的h文件。本系統產生"nnsd_Frame1.h",其中調用的函數為:
JNIEXPORT void JNICALL Java_nnsd_Frame1_makeNoise
(JNIEnv *, jobject, jfloat, jint);
如果僅使用SUN公司的JDK來實現,須用javah.exe將javac.exe生成的class文件去生成對應的h文件,之后并要修改h文件,即須將文件的包層次在調用的函數名上體現出來。
1.3 JAVA應用系統運行
將VC生成的DLL文件拷到JBUILDER運行程序的目錄下,執行程序,就實現了JAVA系統和MATLAB的通信。本示例系統的DLL是"makenoise.dll",即下面介紹的方法所產生的。
如果僅使用SUN公司的JDK來實現,須用javah.exe將javac.exe生成的class文件去生成對應的h文件,之后并要修改h文件,即須將文件的包層次在調用的函數名上體現出來。
1.3 JAVA應用系統運行
將VC生成的DLL文件拷到JBUILDER運行程序的目錄下,執行程序,就實現了JAVA系統和MATLAB的通信。本示例系統的DLL是"makenoise.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)更方便了第二種方法的應用,現本系統的實現就是以之為基礎的。
2.1 MATLAB與VC實現互連
為了使用MATLAB的具體功能,在開發環境中應首先安裝MATLAB工具軟件,之后運行此工具軟件,分別執行"mex -setup;mbuild -setup;cd(prefdir); mccsavepath;"命令。現在再運行VC開發工具,從菜單開始依次打開"Tools->Customize->Add-ins and Macro Files",選中MATLAB Add-in項,就可以看到工具欄中多了一個 。現在VC就可以利用它來得到m文件所對應的c、c++文件。
2.2 開發工具VC運行環境設置
系統開發時,須對VC的開發環境變量進行設置。通過"Tools->Options->Directories"找到的Directories項中添加環境變量。
添加頭文件和庫文件搜索路徑[3]是(本計算機的文件搜索路徑為):
F:MATLAB6P5EXTERNINCLUDE F:MATLAB6P5EXTERNINCLUDECPP F:MATLAB6P5EXTERNLIB F:MATLAB6P5EXTERNLIBWIN32 F:MATLAB6P5EXTERNLIBWIN32MICROSOFTMSVC60
上述為VC編譯MATLAB的m文件生成C++代碼的環境。同時為了編譯JNI的h文件,還須通過菜單Tools.和Project添加如下頭文件和庫文件搜索路徑:
D:JBUILDER6JDK1.3.1INCLUDE D:JBUILDER6JDK1.3.1INCLUDEWIN32
2.4 VC生成DLL[4]
在本系統中,VC建立名稱為makenoise的"MFC APPWizard(dll)"Project,按照VC默認的選項完成工程的創立。
將1.2中生成的nnsd_Frame1.h文件拷貝到系統目錄下,并添加到VC的"FileView"中"HeadFiles"里面。通過MATLAB Add-in將"normrnd.m、rndcheck.m、noise.m"文件添加到VC中,并自動生成VC文件。具體操作步驟如下:
點擊工具欄中"Add m-files to current project"項,在出現的圖中選定如下選項:

圖1 添加m文件的Add-in選擇
按照接著步驟的提示將上述3個m文件添加到項目中。
在VC中為了對外提供可調用的函數,須在"makenoise.cpp"文件中添加:
#include "nnsd_Frame1.h"
JNIEXPORT void JNICALL Java_nnsd_Frame1_makeNoise
(JNIEnv *env, jobject obj, jfloat m, jint n){}
//將原申明的函數的變量名補上,具體實現功能代碼在下面。
為了讓上述導出函數獲得對MATLAB中白噪聲函數的調用,須在此文件中再添加:
#include "math.h"
#include "dblmtrx.h"
//下面申明得到全局matlab的函數
extern void InitializeModule_noise();//初始化
extern void noise(mwArray n, mwArray m);//產生白噪聲函數
extern void TerminateModule_noise();//關閉資源
//dll導出JAVA函數的具體實現部分
JNIEXPORT void JNICALL Java_nnsd_Frame1_makeNoise
(JNIEnv *env, jobject obj, jfloat m, jint n)


{
AfxMessageBox("開始產生白噪聲!");
InitializeModule_noise();
noise(n,m);
TerminateModule_noise();
}

編譯整個程序,于是便得到"makenoise.dll"。
2.3 脫離MATLAB環境運行的支持文件
為了在沒有安裝MATLAB應用軟件的環境下,能夠使用上述的DLL,須在運行此DLL的目錄中添加一些文件,而這些文件可以通過工具欄中的"MATLAB Add-in Packager"獲得。按照此工具默認的配置得到一個運行所需文件的zip壓縮文件,使用時,解壓縮到DLL文件所在的目錄中,就能脫離MATLAB環境使用DLL。
3 結論
采用JAVA完成圖形界面設計、數據管理等,利用MATLAB數學庫完成軟件核心算法設計,很大程度上降低了編程難度和工作量, 縮短開發周期,提高軟件可靠性。尤其利用編譯器調用MATLAB動態連接庫實現脫離MATLAB環境下二者的緊密結合,更極大拓展了MATLAB的應用范圍。基于VC++6.0實現JAVA和MATLAB的通信,深化了JAVA和MATLAB的應用能力。
附注:noise.m文件的內容如下:
function makeNoise(n,m)
c=normrnd(0,m,1,n);
s=‘樣本文件.txt’‘;
fid=fopen(s,‘W’);
fprintf(fid,‘%6.2f’,c);
fclose(fid);

地震讓大伙知道:居安思危,才是生存之道。