近期项目中需要使用matlab跟java做混合开发。主要记录一下,此次开发遇到的问题点。
环境:使用的matlab版本是 R2018b。
当前状况:MATLAB代码已经编写好,且运行成功。需要打成jar包才可以被java调用。
步骤一:
按照教程安装好matlab后,打开matlab,查看当前matlab依赖的jdk版本号:
找到对应的java版本,安装到本机,并配置对应的环境变量。
然后开始打包:
点击package后勾选需要保存打包好的文件路径
点击保存后开始打包, 打包成功后界面
打开输出文件夹,会出现4个文件夹
可以看到最后的jar包名称与上文中输入的一致。这就是我们需要在java中调用的jar。
将该jar包引入到java项目中,榆次同时还需要将MATLAB中的另一个jar也引入java项目,否则调用不成功。在本机的MATLAB阿德安装目录中找到javabuilder.jar一同引入。
至此,MATLAB工程就可以被java程序调用了。
步骤二:
在java项目中引入MATLAB编译好的jar包
在java项目中编写对应代码调用jar,由于我的MATLAB程序输出的是两个参数,因此需要将两个数据分别获取到 ,然后合并到同一个文件中,保存下来后,与在MATLAB中执行后对比,确认运行成功。
import com.mathworks.toolbox.javabuilder.*;
import testhalo.TestHalo;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;public class halotest {public static void main(String[] args) {MWNumericArray input = null;Object[] result = null;TestHalo test = null;try {input = new MWNumericArray(Double.valueOf(15),MWClassID.DOUBLE);test = new TestHalo();
//这里注意 第一个参数 是MATLAB程序会输出几个返回值 从第二个参数向后 才是真正调用MATLAB的jar的入参result = test.testhalo(2,2023d,6d,15d,19d,10d,0d,1d,8000d,60d);saveArrayToFile("E:\\1\\2\\1.txt",result);} catch (MWException e) {e.printStackTrace();} finally {MWArray.disposeArray(input);MWArray.disposeArray(result);test.dispose();}}// 保存数值数组到文件private static void saveArrayToFile(String filename, Object[] response) {try {BufferedWriter writer = new BufferedWriter(new FileWriter(filename));MWNumericArray T = (MWNumericArray) response[0]; // 第一个输出参数 MWNumericArray Halo = (MWNumericArray) response[1]; // 第二个输出参数 int[] haloDimensions = Halo.getDimensions();int[] TDimensions = T.getDimensions();if (haloDimensions.length != TDimensions.length || haloDimensions[0] != TDimensions[0])return;int numRows = haloDimensions[0]; //行数int haloCols = haloDimensions[1]; //列数int tCols = TDimensions[1];for (int i = 1; i <= numRows; i++) {for (int j = 1; j <= haloCols; j++) {int[] index = {i,j};double valueHalo = Halo.getDouble(index);writer.write( Double.toString(valueHalo));if (j <= haloCols) {writer.write("\t");}}for (int k = 1; k <= tCols; k++) {int[] index = {i,k};double valueT = T.getDouble(index);writer.write( Double.toString(valueT));if (k <= haloCols) {writer.write("\t");}}writer.newLine();}writer.close();} catch (IOException e) {e.printStackTrace();}}}
遇到的问题总结:
1.只能接受具有单个入口点的MATLAB函数和MEX文件作为导出函数
当勾选完需要作为主程序入口的文件时会弹窗报错。这是因为勾选的文件有多个程序入口,需要将这些调用方法都拆分到其他文件中,保证这个文件中只有一个主程序调用入口。
2.调用入参传递问题
这行代码是调用MATLAB的jar的入口。可以看到引入的jar包,然后实例化后调用我们在上文中指定的修改后的主程序方法名(根据你自己定义的方法名修改),然后后面的入参,有一点要注意:第一个入参,不是真正的入参,是定义MATLAB的jar的实际返回的数据有几个。从第二个参数开始,才是真正的调用testhalo()的入参。
3.导入java程序后调用报错
这是因为MATLAB中程序被编译成jar包后,涉及到数据格式转换。在java中编写程序调用MATLAB的jar时,需要使用double类型的入参。否则就会报错,参数类型不匹配!!!