近期项目中需要使用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类型的入参。否则就会报错,参数类型不匹配!!!