1. 程式人生 > >M檔案打包成jar包詳解

M檔案打包成jar包詳解

圖片鎮樓

摘要:MATLAB中封裝了種類齊全、功能強大的函式和工具箱等,有時在Java工程中編寫可能花費很多精力,為此可直接將MATLAB中編寫好的功能模組打包成jar包,在Java中進行引用。本文詳細介紹如何將已編寫好的m檔案打包成jar包的軟體安裝以及打包具體步驟,然後介紹瞭如何在Java中呼叫打包好的jar包並給出具體程式碼。其要點如下:

前言

    由於MATLAB在數值計算方面的高效能,大大提高了科研和工作的效率,已逐漸發展成一個具有較高通用性的、帶有眾多實用工具的運算操作平臺。MATLAB中封裝了種類齊全、功能強大的函式和工具箱等,MATLABJava的混合程式設計能幫助我們減少許多編寫程式碼的時間,特別是在已經編寫好MATLAB

程式,需要用Java進行封裝形成一個可執行的獨立程式的時候,這樣做則方便得多。要實現這個功能則需要安裝並配置好Java環境以及MATLAB軟體,利用MATLAB的編譯功能打包jar,然後在Java工程中進行呼叫。以下是詳細介紹。

1.準備工作

1.1 安裝MATLAB

    首先當然需要安裝好MATLAB,已經成功安裝並破解的可以跳過這一步驟。MATLAB R2014a下載與安裝網上用很多教程,也可以通過我的百度網盤下載,裡面有安裝及破解說明。

1.2 安裝jdk

    MATLAB打包成jar包時需要呼叫javac生成class檔案,因此我們需要安裝JDK。由於編譯過程中的可能報錯,大多是由於MATLAB

的版本與JDK的版本不一致所導致的,根據情況需要降低JDK版本,經試驗,MATLAB 2015a2014a 適用jdk1.7MATLAB 2013a 適用jdk1.6,其他的未測試(jdk1.8可能報錯)。
    jdk的安裝步驟網上有許多教程可供參考,限於篇幅,這裡就不作介紹了。值得注意的是,環境變數務必配置正確,否則後面的編譯過程極易報錯。

2. 打包步驟

    這裡我以一個簡單的m程式打包作為例子,介紹其詳細步驟供參考。

一、在MATLAB中編寫m檔案(寫成m函式形式)並除錯通過,我寫好的MATLAB程式如下圖所示

圖片鎮樓
圖片鎮樓

    要打包的函式是test.m,其中呼叫了maxMum.m

函式,上面的程式碼如下
test.m檔案:

function [Mean,Sum,Std,result]=test(input1,input2)
Mean=mean(input1);
Sum=sum(input1);
Std=std(input1);
result=maxMum(input1,input2);
end

maxMum.m檔案:

function result=maxMum(a,b)
Maxb=max(max(b));
result=double(a>Maxb);
end

二、在MATLAB命令列視窗輸入deploytool並回車,在跳出的編譯器選擇介面選擇Library Compiler 如下圖所示

圖片展示

三、彈出的編輯介面如下圖

圖片鎮樓

    1.在介面1號框內選擇Java Package

    2.點選2號框內的加號選擇要打包的檔案;

    3.在3號框內設定包名;

    4.在4號框內修改類名及方法名(為了方便呼叫,建議修改預設的類名)

    5.第5、6號框內分別是執行時所需要的檔案和一起安裝的檔案,一般會系統自動檢測並新增進去;

    6.點選7號框內的Package按鈕進行打包,介面如下

圖片鎮樓

四、等待打包完成,此時會出現三個資料夾如下所示

圖片展示 圖片展示

    上面都完成後,若無錯誤,將預設在當前m檔案所在目錄生成以包名命名的資料夾,在for_testing資料夾內有我們需要的jar檔案。

圖片展示

3. 呼叫jar包

3.1 呼叫方式

    打包完成我們還是有必要了解下生成的這幾個檔案,for_testing資料夾中除了jar檔案還有m檔案轉換的對應java程式,例如開啟for_testing資料夾下的test(先前編譯時自設的包名)資料夾,就有我們想要的Test類的java檔案,開啟可檢視程式碼以及呼叫方式。

圖片展示

    除了上述方式可以檢視呼叫方法,還有更簡單的方式。開啟在生成資料夾下路徑為for_redistribution_files_only\doc\html\index.html檔案,可以檢視test所有過載函式的使用說明,如下

圖片展示

    這裡最適合的方法是紅色框圈出的,該方法的呼叫說明如下

解讀:
    引數nargout 第一個輸入引數是整形,表示的是輸出的個數,在本例中有四個輸出(Mean,Sum,Std,result),因此設定為4;
    引數rhs 與M函式對應的輸入引數,為Object型別,本例中有兩個輸入引數(input1,input2)。雖說Object類是Java中其他所有類的基類,這裡的兩個引數是陣列、int型等型別都是可以的,但建議使用MWNumericArray型別,後面詳細介紹;
    函式返回值: 一個包含nargout個返回引數的Object型別陣列,每個元素對應M函式中的每個輸出結果。

3.2 具體步驟

    有了以上的基本認識,終於可以開始正式使用jar包了。

一、新建java工程,新建一個java程式用於使用jar包,新增必要的Jar

    因為是MATLAB打包的jar包,需要依賴MATLAB中的相關函式,所以需要的Jar包除了我們前面生成的test.jar 包還要 javabuilder.jar 包,它的路徑在MATLAB的安裝目錄下的toolbox\javabuilder\jar\javabuilder.jar ,可以將兩個jar包拷出來放到一個自建的資料夾中,方便下面新增jar包。

    1.在新建的工程資料夾右擊選擇Properties進入屬性介面

    2.選擇左側Java Build Path(1號框),點選右邊的Libraries(2號框),點選Add External JARs(3號框),找到上面說的javabuilder.jartest.jar包的路徑將兩個包新增進庫中(4號框)

    3.點選右下角OK按鈕,完成jar包新增。

圖片展示

二、在新建的java程式中匯入包,即輸入以下程式碼

import com.mathworks.toolbox.javabuilder.*;
import test.Test;//此處的test為前面編譯時設定的包名,Test為選定的類名

三、在主方法中呼叫函式,輸入如下程式碼

import java.util.ArrayList;
import com.mathworks.toolbox.javabuilder.*;
import test.Test;//此處的test為前面的包名,Test為選定的類名

/** 在java中呼叫matlab轉的jar包示例
 * @author W.X
 * @version 1.0 10/5/2018
 * */
public class Main {
	public static void main(String[] args) {
		MWNumericArray input1 = null;// 輸入引數一
		MWNumericArray input2 = null;// 輸入引數二
		Object[] result = null;      // 輸出結果
		Test test = null;

		try {
			ArrayList<Integer> list = new ArrayList<>();
			for (int i = 0; i < 15; i++){
				list.add(i+1);
			}
			// 引數一為一個從1到15的陣列
			input1 = new MWNumericArray(list.toArray(),
					MWClassID.DOUBLE);
			// 引數二為10
			input2 = new MWNumericArray(Double.valueOf(10),
					MWClassID.DOUBLE);

			test = new Test();// 例項化

			result = test.test(4, input1,input2);// 呼叫test方法

			double Mean=((MWNumericArray) result[0]).getDouble(1);// 第一個輸出
			double Sum=((MWNumericArray) result[1]).getDouble(1); // 第二個輸出
			double Std=((MWNumericArray) result[2]).getDouble(1); // 第三個輸出

			double[] R =new double[15];                           // 第四個輸出,為一個數組
			for(int i=0;i<15;i++){
				R[i]=((MWNumericArray) result[3]).getDouble(i+1); // 從result中依次取出第四個輸出
				System.out.println(R[i]);
			}

			// 列印結果
			System.out.println(Mean);
			System.out.println(Sum);
			System.out.println(Std);


		} 
		catch (MWException e) {
			e.printStackTrace();
		} 
		finally {
			MWArray.disposeArray(input1);
			MWArray.disposeArray(input2);
			MWArray.disposeArray(result);
			test.dispose();
		}
	}
}

程式碼說明:

    程式碼看似較長,其實非常簡單。程式碼11-14行聲明瞭所有引數及物件,17-26行是對兩個輸入引數賦值。對於MATLAB來說原m函式中的兩個輸入引數可以是陣列也可以是某個數,在java中呼叫時同樣如此,作為示例這裡我的第一個引數是個陣列,第二個引數是一個實數。陣列採用的是ArrayList型,實數是double型,兩個引數都轉化成MWNumericArray的型別進行呼叫。

    程式碼第30行,呼叫test方法得到結果,結果儲存在resultObject陣列中。第32-34行依次從result的每個元素中取出第一、二、三個結果(Mean、Sum、Std),由於resultObject型而我們往往需要的是double型的結果資料,因此需要進行型別轉換轉換為MWNumericArray型然後引用其getDouble方法轉化成double

    程式碼第36-40行,取出第四個結果並放在double型陣列R中,由於第四個結果是陣列型所以取出時需要藉助迴圈結構依次賦值取出。

結束語

    至此從編譯至呼叫的步驟完成,許多MATLAB中好用的m函式在java中也能輕鬆使用了,不得不說使用MATLAB打包成jar確實為一個簡單粗暴又好用的方法。但同時由於兩種語言的內部差異以及其中的複雜轉換使得在java中呼叫時執行速度減慢,如果特別在意執行速度建議還需要另做優化調整或採用純java編寫。

    由於博主能力有限,博文中提及的方法與程式碼即使經過測試,也難免會有疏漏之處。希望您能熱心指出其中的錯誤,以便下次修改時能以一個更完美更嚴謹的樣子,呈現在大家面前。同時如果有更好的實現方法也請您不吝賜教。