Main Content

Deploy MATLAB Class That Inherits from MATLAB Handle Class

Since R2024a

Data API: MATLAB® Data Array

This example shows how to package a MATLAB class that inherits from a MATLAB handle class and deploy it within a C++ application. It uses the MATLAB Data API for managing data exchange between the MATLAB function and the C++ application. The workflow is supported on Windows®, Linux®, and macOS.

Prerequisites

  • Create a new work folder that is visible to the MATLAB search path. This example uses a folder named work.

  • Verify that you have set up a C++ development environment. For details, see Set Up C++ Development Environment. This example uses MATLAB as a C++ development environment. Therefore, verify that you have a C++ compiler installed by typing mbuild -setup at the MATLAB command prompt.

  • Verify that you have met all of the MATLAB Compiler SDK™ C++ target requirements. For details, see MATLAB Compiler SDK C++ Target Requirements.

  • End users must have an installation of MATLAB Runtime to run the application. For details, see Download and Install MATLAB Runtime.

    For testing purposes, you can use an installation of MATLAB instead of MATLAB Runtime when running the C++ application.

Handle Class Support

When you deploy a MATLAB class that inherits from a MATLAB handle class, the following functionality is now supported:

  • Copy Behavior: The .hpp file generated by MATLAB Compiler SDK allows the creation of C++ objects that mimic the reference-type behavior of MATLAB handle classes. When you create a copy of these C++ objects in your application, both the original and the copy refer to the same underlying object, similar to MATLAB handle object behavior.

  • Relational Operators: C++ objects created based on the MATLAB handle class definitions in the .hpp file support relational operations. This allows for the use of standard relational operators (==, !=, <, >, <=, >=) in C++, similar to their functionality in MATLAB.

Create MATLAB Function

Create a MATLAB file named BankAccount.m with the following code:

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

Established MATLAB users may find it unconventional to see a properties block in a class and an arguments block in a method or function, each detailed with data type information. Both blocks let you represent C++ data types with an equivalent MATLAB type. For instance, if your C++ application employs a double data type representing a value, you can now represent that in MATLAB as a double. You can also specify a MATLAB object as an argument or property type. For example, the withdraw method specifies BankAccount as a type for one of the input arguments. This option to specify types is useful in situations where a C++ application has strict type requirements. For details, see Data Type Mappings Between C++ and Strongly Typed MATLAB Code.

Test the MATLAB class at the command prompt.

%% 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

Note

MATLAB

functions that use varargin and varargout are unsupported.

Package MATLAB Function Using compiler.build.cppSharedLibrary

Create a code archive (.ctf file) and header (.hpp file) from the MATLAB function using the compiler.build.cppSharedLibrary function.

buildResults = compiler.build.cppSharedLibrary("BankAccount.m",...
    OutputDir=".\output", Verbose="on");

The function produces a suite of files, as enumerated below, and places them in the specified output directory. Among these, the key files utilized during the integration process are the code archive (.ctf file) containing the MATLAB code and the corresponding header (.hpp file). For information on the other files, see Files Generated After Packaging MATLAB Functions.

P:\MATLAB\WORK\OUTPUT
│   GettingStarted.html
│   includedSupportPackages.txt
│   mccExcludedFiles.log
│   readme.txt
│   requiredMCRProducts.txt
│   unresolvedSymbols.txt
│
└───v2
    └───generic_interface
            BankAccount.ctf
            BankAccountv2.hpp
            readme.txt

To finalize integration, you need the BankAccount.ctf code archive file and the BankAccountv2.hpp header file from the generic_interface folder. You can view the header file here:

 BankAccountv2.hpp

Mapping Between MATLAB Class and C++ Header File

MATLAB Class ElementC++ Header Elementa

classdef BankAccount < handle

class definition inheriting from MATLAB handle class

class BankAccount : public MATLABHandleObject<MATLABControllerType>

The concept of a MATLABhandle class is replicated through the use of MATLABHandleObject in C++.

function obj = BankAccount(initialBalance) constructor

BankAccount(std::shared_ptr<MATLABControllerType> _matlabPtr, double initialBalance)

function deposit(obj, amount)

method

void deposit(double amount)

function withdraw(obj, amount)

method

void withdraw(double amount)

function bal = checkBalance(obj) method

matlab::data::Array checkBalance<1>()

Relational operators inherited from MATLAB handle class

  • ==

  • !=

  • <

  • >

  • <=

  • >=

bool operator==

bool operator!=

bool operator<

bool operator>

bool operator<=

bool operator>=

a Input arguments are in C++ data types corresponding to those defined in the MATLAB class' arguments block.

Note

The generated artifacts do not include MATLAB Runtime or an installer. To create an installer using the buildResults object, see compiler.package.installer.

Integrate MATLAB Code Archive into C++ Application

You can finalize the integration process in your preferred C++ development environment, including MATLAB or alternatives such as Microsoft® Visual Studio® on Windows. This example, however, uses MATLAB as a C++ development environment. For details, see Set Up C++ Development Environment.

To integrate the generated MATLAB code archive (.ctf file) and header (.hpp file) into a C++ application, adhere to these guidelines:

  • Use a #include directive to incorporate the generated header file (.hpp file) in your C++ application code.

  • Ensure the code archive (.ctf file) is positioned in a location that the C++ executable can access.

Completing the integration step requires proficient C++ skills for writing application code. You can use the following sample C++ application code as guide when writing your own application.

  1. In the work folder for this example create a new file named BankAccountCppConsoleApp.cpp with the following code.

     BankAccountCppConsoleApp.cpp

  2. Compile and link the application by executing the mbuild function at the MATLAB command prompt.

    mbuild -v BankAccountCppConsoleApp.cpp -outdir output\bin

Handle Code Archive (.ctf file)

To ensure your C++ application can access the code archive (.ctf file) containing MATLAB code, place the file in a location accessible to the executable. For this example we are going to do this by setting the CPPSHARED_BASE_CTF_PATH environment variable in the MATLAB desktop environment.

setenv("CPPSHARED_BASE_CTF_PATH","P:\MATLAB\work\output\v2\generic_interface")

If you're using Visual Studio, see Set Environment Variables in Visual Studio.

For a complete list of code archive (.ctf file) placement options, see Code Archive (.ctf file) Placement.

Run C++ Application

For testing purposes, you can run the application from MATLAB command prompt. This does not require a MATLAB Runtime installation.

!output\bin\BankAccountCppConsoleApp.exe
Created a bank account with an initial balance of $100
Deposited $50
Current balance: $150
Withdrew $30
Current balance: $120
Created a joint account
Are the account and joint account the same? true
Original account:
Current balance: $140
Joint account:
Current balance: $140

See Also

|

Related Topics