杰瑞科技汇

Java如何直接调用Matlab函数?

使用 MATLAB Engine API (推荐)

这是 MathWorks 官方推荐的方式,也是最强大、最灵活的方式,它允许你的 Java 应用程序在运行时启动一个 MATLAB 进程,并直接调用其中的函数和脚本,传递和接收数据。

核心原理: Java 通过一个本地接口与 MATLAB 的核心引擎进行通信,Java 发送命令和数据给 MATLAB 引擎,引擎执行后返回结果。

优点:

  • 功能最全:可以调用任何 MATLAB 函数(包括内置函数和自定义函数),甚至可以执行脚本。
  • 双向交互:可以轻松地将 Java 对象(如数组)传递给 MATLAB,并将 MATLAB 的结果(如数值、矩阵、结构体)传回 Java。
  • 官方支持:由 MathWorks 官方维护,稳定性和兼容性最好。

缺点:

  • 依赖 MATLAB 环境:目标机器上必须安装 MATLAB。
  • 性能开销:启动 MATLAB 进程需要时间,进程间通信也有一定的性能开销,不适合极高频率的调用。

详细步骤与代码示例

前提条件:

  1. 已安装 MATLAB。
  2. 在 MATLAB 中进行配置,让 Java 能找到 MATLAB 的库。
    • 打开 MATLAB。
    • 在命令窗口输入 matlab -desktop -jvm 确保启动了 JVM。
    • 运行 matlab.engine.shareEngine 来共享引擎实例(可选,但推荐)。
    • 关键步骤:找到 MATLAB 的安装路径,C:\Program Files\MATLAB\R2025a\extern\engines\java,将这个路径添加到你的 Java 项目的类路径中。

示例代码:

假设我们有一个简单的 MATLAB 函数 add.m

% add.m
function sum = add(a, b)
    sum = a + b;
end

Java 代码

import matlab.engine.*;
public class MatlabEngineExample {
    public static void main(String[] args) {
        try {
            // 1. 启动 MATLAB 引擎
            // 这个调用可能会阻塞,直到 MATLAB 引擎完全启动
            System.out.println("Starting MATLAB Engine...");
            MatlabEngine eng = matlab.engine.MatlabEngine.startMatlab();
            // 2. 调用 MATLAB 函数
            // 调用 add(5, 10),并获取第一个输出参数
            System.out.println("Calling MATLAB function add(5, 10)...");
            int result = eng.feval("add", 5, 10);
            System.out.println("Result from MATLAB: " + result);
            // 3. 传递数组
            System.out.println("\nPassing an array to MATLAB...");
            double[] javaArray = {1.0, 2.0, 3.0, 4.0, 5.0};
            // 将 Java 数组转换为 MATLAB 的 double 类型数组
            // MATLAB 的 double 数组对应 Java 的 double[].class
            eng.put("matlabArray", javaArray); // 将 javaArray 变量存入 MATLAB 工作空间,名为 matlabArray
            // 在 MATLAB 中计算数组平方和
            double sumOfSquares = eng.feval("sum", eng.feval("power", "matlabArray", 2));
            System.out.println("Sum of squares from MATLAB: " + sumOfSquares);
            // 4. 执行脚本
            System.out.println("\nExecuting a MATLAB script...");
            eng.eval("disp('Hello from MATLAB script!');");
            eng.eval("x = 100; y = 200; z = x * y;");
            int scriptResult = eng.getVariable("z"); // 从 MATLAB 工作空间获取变量 z
            System.out.println("Result from script (z = x * y): " + scriptResult);
            // 5. 关闭 MATLAB 引擎
            System.out.println("\nClosing MATLAB Engine...");
            eng.close();
        } catch (MatlabEngineException e) {
            System.err.println("Error with MATLAB Engine: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

如何编译和运行

  • IDE (如 IntelliJ IDEA 或 Eclipse):

    1. 创建一个新的 Java 项目。
    2. matlabengine.jar (位于 MATLAB\extern\engines\java 目录下) 添加到项目的库中。
    3. MATLAB\bin\win64 (或对应你的系统的目录,如 darwinlinux) 添加到 JVM 的 java.library.path,这可以通过在 VM options 中添加 -Djava.library.path="C:\Program Files\MATLAB\R2025a\bin\win64" 来实现。
    4. 将上面的 Java 代码粘贴到主类中,然后运行。
  • 命令行:

    # 假设 matlabengine.jar 在当前目录,.dll/.so 文件在系统路径中
    javac -cp ".;C:\Program Files\MATLAB\R2025a\extern\engines\java\matlabengine.jar" MatlabEngineExample.java
    java -cp ".;C:\Program Files\MATLAB\R2025a\extern\engines\java\matlabengine.jar" MatlabEngineExample

将 MATLAB 代码编译为 Java 库 (JAR)

这种方式将你的 MATLAB 函数编译成一个独立的 Java JAR 文件,这样你的 Java 应用程序就可以像调用普通 Java 类一样调用它,而无需在运行时安装 MATLAB。

核心原理: 使用 MATLAB 的 Compiler ( mcc) 工具,将 .m 文件编译成 Java 可调用的代码,并打包成 JAR 文件,这本质上是将 MATLAB 代码翻译成 Java 字节码。

优点:

  • 独立运行:最终应用不依赖 MATLAB 环境,只需安装 JRE。
  • 性能较好:没有进程间通信的开销,直接调用本地代码。

缺点:

  • 功能受限:只能编译函数,不能直接编译脚本,某些高级 MATLAB 特性(如特定工具箱函数)可能不被支持。
  • 编译过程复杂:需要配置 Compiler SDK,并且生成的 JAR 文件可能依赖其他第三方库。
  • 版本兼容性:编译时使用的 MATLAB 版本和运行时 JRE 版本需要匹配。

详细步骤与代码示例

前提条件:

  1. 已安装 MATLAB Compiler SDK (通常是 MATLAB 安装时的一个可选组件)。
  2. 需要一个 .m 文件。

示例代码:

还是用 add.m 函数。

编译步骤

  1. 打开 MATLAB
  2. 在命令窗口输入以下命令来编译 add.m
    % -d: 指定输出目录
    % -W java:JAR -T jar:指定生成类型为 JAR
    % add: 要编译的 MATLAB 函数名
    % add_class: 生成的 Java 类名
    mcc -d 'output_folder' -W java:MatlabAddJAR -T jar:add add.m

    执行后,MATLAB 会在 output_folder 目录下生成 MatlabAddJAR.jar 以及一些相关的 .class 文件和依赖库。

Java 代码

import matlab.add_jar.*; // 导入编译后生成的包
public class MatlabJARExample {
    public static void main(String[] args) {
        try {
            // 创建 MATLAB 库的实例
            MatlabAddJAR matlabLib = new MatlabAddJAR();
            // 调用编译后的函数
            // 注意:函数名变成了大开头的 "Add"
            Object[] result = matlabLib.Add(15, 25);
            // 结果是一个 Object 数组,第一个元素是返回值
            int sum = (Integer) result[0];
            System.out.println("Result from compiled JAR: " + sum);
        } catch (Exception e) {
            System.err.println("Error calling compiled MATLAB function: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

如何编译和运行

  1. 将编译生成的 MatlabAddJAR.jar 以及它依赖的所有 .jar 文件(在 output_folder 目录下)添加到你的 Java 项目的类路径中。
  2. 像运行普通 Java 项目一样运行上述代码。

通过进程调用 (最简单,但功能最弱)

这种方式不使用任何官方 API,而是通过 Java 的 Runtime.exec()ProcessBuilder 来启动 MATLAB 进程,并像在命令行中一样执行命令。

核心原理: Java 启动一个独立的 MATLAB 进程,通过标准输入向它发送命令,通过标准输出读取结果。

优点:

  • 实现简单:无需复杂的配置,只需要能调用 matlab.exe
  • 不依赖 API:不使用 matlabengine.jar

缺点:

  • 功能极弱:无法传递复杂的数据结构(如多维数组),只能通过字符串命令和文件进行交互。
  • 通信困难:解析标准输出非常繁琐且容易出错。
  • 性能差:每次调用都需要启动和销毁一个完整的 MATLAB 进程,开销巨大。

详细步骤与代码示例

前提条件:

  1. 系统环境变量 PATH 中包含 MATLAB 的 bin 目录,以便能找到 matlab.exe

示例代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class MatlabProcessExample {
    public static void main(String[] args) {
        try {
            // 构建命令
            // -r 后面跟着要执行的 MATLAB 命令,用分号隔开
            // -nodisplay -nosplash 表示不显示图形界面
            String[] command = {
                "matlab",
                "-nodisplay",
                "-nosplash",
                "-r", "add(5, 10); disp('Process finished'); exit;"
            };
            // 启动进程
            Process process = Runtime.getRuntime().exec(command);
            // 读取进程的标准输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            System.out.println("Output from MATLAB process:");
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 读取进程的错误输出
            BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            System.out.println("\nErrors from MATLAB process:");
            while ((line = errorReader.readLine()) != null) {
                System.err.println(line);
            }
            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("\nMATLAB process exited with code: " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

总结与对比

特性 MATLAB Engine API 编译为 JAR 通过进程调用
依赖环境 必须安装 MATLAB 仅需 JRE 必须安装 MATLAB
功能完整性 最强 (所有函数、脚本、数据类型) 较强 (仅编译的函数) 最弱 (仅命令行)
性能 中等 (有进程通信开销) (直接调用) (进程启动/销毁开销大)
易用性 配置稍复杂,调用简单 编译复杂,调用简单 配置简单,调用和解析困难
适用场景 开发阶段、需要交互式计算、功能要求高 部署阶段、追求高性能和独立性 快速原型、执行简单脚本、无法使用 API 时

如何选择?

  • 如果你正在开发一个原型,或者你的应用环境就是安装了 MATLAB 的服务器/工作站,并且需要调用大量 MATLAB 函数,首选 MATLAB Engine API,这是最灵活、最强大的方案。
  • 如果你需要将你的应用分发给最终用户,而这些用户没有安装 MATLAB,那么选择编译为 JAR 的方式,这是部署和分发的标准方案。
  • 如果你只是想偶尔执行一个非常简单的 MATLAB 命令,并且不想引入复杂的依赖,可以考虑通过进程调用,但要准备好处理字符串解析的麻烦,对于大多数严肃的应用,不推荐此方法。
分享:
扫描分享到社交APP
上一篇
下一篇