主要内容

本页采用了机器翻译。点击此处可查看英文原文。

部署从 MATLAB 句柄类继承的 MATLAB

数据 API:MATLAB® Data Array for Java®

此示例演示了如何打包一个继承自 MATLAB 句柄类的 MATLAB 类,并将其部署到 Java 应用程序中。它使用 MATLAB Data API for Java 来管理 MATLAB 代码与 Java 应用程序之间的数据交换。该工作流支持Windows®、Linux®macOS

前提条件

  • 创建一个对 MATLAB 搜索路径可见的新工作文件夹。此示例使用名为 work 的文件夹。

  • 请确认您已搭建好 Java 开发环境。有关详细信息,请参阅 设置 Java 开发环境

  • 请确认您已满足所有 MATLAB Compiler SDK™ Java 目标要求。有关详细信息,请参阅 MATLAB Compiler SDK Java 目标要求

  • 最终用户必须安装 MATLAB Runtime 才能运行应用程序。有关详细信息,请参阅下载并安装 MATLAB Runtime

    出于测试目的,您可以使用安装的 MATLAB 来代替 MATLAB Runtime

数据管理

要在已部署的 MATLAB 代码与 Java 应用程序之间交换数据,请使用适用于 Java 的 MATLAB Data API。MATLAB 引擎也使用此 API。有关详细信息,请参阅 Java Data Type Conversions

创建从 MATLAB Handle 类继承的 MATLAB

使用以下代码创建一个名为 BankAccount.m 的 MATLAB 文件:

classdef BankAccount < handle
    % BankAccount - A class for managing a bank account.
    %
    % This class provides methods to deposit, withdraw, and check the 
    % balance of a bank account.
    %
    % BankAccount Properties:
    %   Balance - The current balance of the account (private access).
    %
    % BankAccount Methods:
    %   BankAccount - Constructor, initializes account with a balance.
    %   deposit - Deposit money into the account.
    %   withdraw - Withdraw money from the account.
    %   checkBalance - Check the current balance of the account

    properties (Access = private)
        Balance (1,1) double {mustBeReal}
    end
    
    methods
        % Constructor to initialize the account with a balance
        function obj = BankAccount(initialBalance)
            arguments (Input)
                initialBalance (1,1) double {mustBeReal}
            end
            if nargin == 0
                initialBalance = 0;
            end
            obj.Balance = initialBalance;
        end
        
        % Method to deposit money
        function deposit(obj, amount)
            arguments (Input)
                obj (1,1) BankAccount
                amount (1,1) double {mustBeReal}
            end
            if amount > 0
                obj.Balance = obj.Balance + amount;
            else
                error('Amount must be positive');
            end
        end
        
        % Method to withdraw money
        function withdraw(obj, amount)
            arguments (Input)
                obj (1,1) BankAccount
                amount (1,1) double {mustBeReal}
            end
            if amount <= obj.Balance && amount > 0
                obj.Balance = obj.Balance - amount;
            else
                error('Insufficient funds or invalid amount');
            end
        end
        
        % Method to check the balance
        function bal = checkBalance(obj)
            arguments (Input)
                obj (1,1) BankAccount
            end
            arguments (Output)
                bal (1,1) double {mustBeReal}
            end
            bal = obj.Balance;
        end
    end
end

在命令提示符下测试 MATLAB 类。

%% Create a new bank account with an initial balance of 100
account = BankAccount(100);

%% Deposit 50 into the account
account.deposit(50);
disp(['Balance after deposit: ', num2str(account.checkBalance())]);

%% Withdraw 30 from the account
account.withdraw(30);
disp(['Balance after withdrawal: ', num2str(account.checkBalance())]);

%% Create a joint account that references the same existing account
jointAccount = account;

%% Deposit 20 using the shared reference
jointAccount.deposit(20);
disp(['Balance from sharedAccount: ', num2str(jointAccount.checkBalance())]);
disp(['Balance from original account: ', num2str(account.checkBalance())]);

Balance after deposit: 150
Balance after withdrawal: 120
Balance from sharedAccount: 140
Balance from original account: 140

使用 compiler.build.javaPackage 创建 Java

使用 compiler.build.javaPackage 函数,根据 MATLAB 函数生成的数据生成代码存档(.ctf 文件)。

buildResults = compiler.build.javaPackage( ...
    "BankAccount.m",...
    Interface="matlab-data",...
    Verbose="on", OutputDir=".\output",....
    PackageName="com.example.Banking")

尽管在 compiler.build.javaPackage 函数中指定 PackageName 并非强制要求,但强烈建议您指定。指定包名可以使生成的代码拥有更简洁、更易预测的 Java 命名空间。如果省略该参数,系统将使用名为 example 的默认根包,这可能会导致您的 Java 应用程序的包结构杂乱无章或令人困惑。

当您将 MATLAB 函数打包以供 Java 集成时,该过程会在您指定的输出目录中生成多个文件。其中,Java 集成所需的唯一关键文件是代码存档(.ctf 文件),其中包含您打包的 MATLAB 代码和资源。有关其他文件的详细信息,请参阅 打包 MATLAB 函数后生成的文件

P:\MATLAB\WORK\OUTPUT
    requiredMCRProducts.txt
    GettingStarted.html
    readme.txt
    buildresult.json
    unresolvedSymbols.txt
    includedSupportPackages.txt
    mccExcludedFiles.log
    Banking.ctf

No subfolders exist

在使用 MATLAB Data API 处理 Java 时,compiler.build.javaPackage 函数会生成一个 .ctf 文件,但不会生成包含 Java 包装器的 JAR 文件。有关详细信息,请参阅 MATLAB Data API for Java 工作流

MATLAB 代码集成到 Java 应用程序中

您可以在自己偏好的 Java 开发环境中完成集成过程,包括使用文本编辑器配合 Java 开发工具包 (JDK) 的命令行工具,或者在 Windows、macOS 和 Linux 上使用 IntelliJ IDEA 和 Visual Studio Code 等替代方案。有关详细信息,请参阅 设置 Java 开发环境

使用 Java 命令行 API 构建应用程序

  1. 创建一个 Java 包装类,以便在 Java 应用程序中直接使用 MATLAB BankAccount 类。

     BankAccount.java

    • 构造函数 BankAccount(MatlabRuntime runtime, double initialBalance) 通过调用以下代码来创建 MATLAB 对象:

      this.accountObject = runtime.feval("BankAccount", initialBalance);
      
      这将创建一个新的 MATLAB BankAccount 实例,并将其绑定到 Java。

    • 在 MATLAB 中,句柄类采用引用语义,这意味着多个变量可以引用同一个对象实例;而在 Java 中,这种行为通过 HandleObject 引用得以保留,从而允许不同的 Java 对象与同一个底层 MATLAB 句柄对象进行交互。

    • 包装器中的每个 Java 方法都对应一个 MATLAB 方法,该方法通过 runtime.feval() 执行。例如:

      • deposit(double amount) 调用了 MATLAB deposit 方法。

      • withdraw(double amount) 调用了 MATLAB withdraw 方法。

      • checkBalance() 调用 MATLAB checkBalance 方法,并返回一个 double 值。

  2. 编写一个驱动程序,用于初始化 MATLAB Runtime,并使用包装器执行操作。

     BankAccountExample.java

    • 驱动程序使用打包的 MATLAB .ctf 文件的路径来初始化 MATLAB Runtime

    • 在运行时会话中,performBankingOperations(runtime) 方法演示了可以执行的各种操作。

  3. 通过将类路径设置为包含 matlabruntime.jar 来编译您的 Java 代码。

    set MATLABROOT=C:\Program Files\MATLAB\R2026a
    
    javac -classpath ".;%MATLABROOT%\toolbox\javabuilder\jar\matlabruntime.jar" BankAccount.java BankAccountExample.java
  4. 通过将类路径设置为包含 matlabruntime.jar,并配置对本机运行时库的访问权限,来运行您的 Java 应用程序。有关详细信息,请参阅 设置 MATLAB 库路径以测试已部署的应用程序

    java -classpath ".;%MATLABROOT%\toolbox\javabuilder\jar\matlabruntime.jar" BankAccountExample
    
    Starting BankAccountExample ...
    MATLAB Runtime started successfully
    Creating bank account...
    Bank account created successfully
    Depositing 50...
    Balance after deposit: 150.0
    Withdrawing 30...
    Balance after withdrawal: 120.0
    Creating joint account reference...
    Depositing 20 using joint account...
    Balance from joint account: 140.0
    Balance from original account: 140.0
    

    如果在未设置环境变量以访问来自 MATLAB 或 MATLAB Runtime 的本机运行时库的情况下运行 Java 应用程序,将会导致 java.lang.UnsatisfiedLinkError

    注意

    在安装了完整 MATLAB 版本的计算机上测试应用程序时,您可以使用 MATLAB 安装来配置对原生库的访问。

    在使用 MATLAB Runtime 的部署场景中,您必须在 MATLAB Runtime 的安装目录中明确指定本机库的位置。这种区分确保了已部署的应用程序能够独立于完整的 MATLAB 安装环境运行。

    有关详细信息,请参阅:

另请参阅

主题