Pass C++ Structures to Deployed MATLAB Functions
This example shows how to pass C++ structures to a MATLAB® function deployed within a C++ application. The workflow is supported on Windows®, Linux®, and macOS systems.
To pass C++ structs to MATLAB functions, in your application code, you must start MATLAB Runtime in IN_PROCESS
mode. You need to use the
USING_TYPE_WITH_MATLAB
macro to inform MATLAB about the custom C++ types, ensuring proper recognition and handling
during function calls. Additionally, you must use the matlab::cpplib::MATLABLibrary::feval
method in your C++ code to evaluate
and execute the MATLAB functions when passing these structures.
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 C++
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.
Create C++ Header File Containing Namespace and Struct Definitions
Create a header file named cppstruct.hpp
that includes a
namespace and structure definitions for the data you want to pass to the
deployed MATLAB function.
#include <vector>
#include <string>
#include <map>
// Define a namespace for the struct definitions
namespace cppstruct {
// Define a struct for the input data
struct InputStruct {
std::vector<double> temperatures;
std::vector<double> pressures;
};
// Define a struct for the statistical results of each field
struct FieldStats {
double mean;
double std;
double max;
};
// Define a struct for the output data
struct OutputStruct {
FieldStats temperatures;
FieldStats pressures;
};
}
The cppstruct.hpp
header file defines a namespace
cppstruct
that contains three structures:
InputStruct
, FieldStats
, and
OutputStruct
.
InputStruct
holds vectors of temperature and pressure data.FieldStats
stores the following statistical results for a field: mean, standard deviation, and maximum value.OutputStruct
is a nested structure that containsFieldStats
for both temperatures and pressures.
Generate MATLAB Interface to C++ Header File
Generate a MATLAB interface for the C++ header file named
cppstruct.hpp
using the clibgen.buildInterface
function. In this particular case, we
chose to name the interface data
, but in other cases, you can
use different names.
clibgen.buildInterface("cppstruct.hpp", InterfaceName="data")
This creates a folder named data
and generates a DLL named
dataInterface.dll
. The
clibgen.buildInterface
function follows the convention
of appending the word Interface
to the interface name you
provide.
Add Interface to MATLAB Path
To use the C++ structures in your MATLAB code, add the interface folder to the MATLAB path.
addpath("P:\MATLAB\work\data")
Create MATLAB Function
Create a MATLAB file named analyzeData.m
with the following
code:
function outputStruct = analyzeData(inputStruct) % analyzeData Analyzes numeric fields in a C++ struct and returns % statistical measures. % % This function takes 'inputStruct' as input, which is a MATLAB % representation of a C++ struct. This representation is generated using % the clibgen.buildInterface function. The function performs statistical % analysis on each numeric field within the struct and returns the results % in a new struct 'outputStruct'. The analyses include computing the mean, % standard deviation, and maximum value for each numeric field. % % Inputs: % inputStruct - A MATLAB representation of a C++ struct % (clib.data.cppstruct.InputStruct) that has temperature and pressure % data. It contains the fields: % - temperatures: a clib.array.data.Double array of temperature values % - pressures: a clib.array.data.Double array of pressure values % % Outputs: % outputStruct - A MATLAB representation of a C++ struct % (clib.data.cppstruct.OutputStruct) with the same fields as % 'inputStruct'. For each numerical array in 'inputStruct', the % corresponding field in 'outputStruct' is a struct containing: % - mean: Mean value of the numerical array % - std: Standard deviation of the numerical array % - max: Maximum value of the numerical array arguments (Input) inputStruct (1,1) clib.data.cppstruct.InputStruct end arguments (Output) outputStruct (1,1) clib.data.cppstruct.OutputStruct end % Initialize outputStruct outputStruct = clib.data.cppstruct.OutputStruct; % Perform analysis on 'temperatures' field if isa(inputStruct.temperatures, 'clib.array.data.Double') % Cast C++ clib.array.data.Double array to MATLAB double array doubleTemperatures = double(inputStruct.temperatures); % Calculate mean outputStruct.temperatures.mean = mean(doubleTemperatures); % Calculate standard deviation outputStruct.temperatures.std = std(doubleTemperatures); % Calculate max value outputStruct.temperatures.max = max(doubleTemperatures); else warning('Field temperatures is not numeric and was skipped.'); end % Perform analysis on 'pressures' field if isa(inputStruct.pressures, 'clib.array.data.Double') % Cast C++ clib.array.data.Double array to MATLAB double array doublePressures = double(inputStruct.pressures); % Calculate mean outputStruct.pressures.mean = mean(doublePressures); % Calculate standard deviation outputStruct.pressures.std = std(doublePressures); % Calculate max value outputStruct.pressures.max = max(doublePressures); else warning('Field pressures is not numeric and was skipped.'); end end
To use C++ structs in a MATLAB function, you need to specify the argument definitions in the
function's arguments
block. These definitions indicate that the C++ structs
defined in the cppstruct.hpp
header file will be used. First,
ensure the folder containing the generated MATLAB interface files is added to the MATLAB path. The structures defined in the header file are accessed in
MATLAB with the naming convention
clib.
.
For example, in this case, you use
<interface_name>.<namespace>.<structure_name>
clib.data.cppstruct.InputStruct
for the input structure
and clib.data.cppstruct.OutputStruct
for the output
structure.
For details on data type mapping, see C++ to MATLAB Data Type Mapping.
Test the MATLAB function at the command prompt.
input = clib.data.cppstruct.InputStruct; input.temperatures = [72, 75, 69, 68, 70]; input.pressures = [30, 29.5, 30.2, 29.9, 30.1]; output = analyzeData(input) disp("Temperatures:") disp(output.temperatures) disp("Pressures:") disp(output.pressures)
output = OutputStruct with properties: temperatures: [1×1 clib.data.cppstruct.FieldStats] pressures: [1×1 clib.data.cppstruct.FieldStats] Temperatures: FieldStats with properties: mean: 70.8000 std: 2.7749 max: 75 Pressures: FieldStats with properties: mean: 29.9400 std: 0.2702 max: 30.2000
Package MATLAB Function Using compiler.build.cppSharedLibrary
Create a code archive (.ctf
file) from the MATLAB function using the compiler.build.cppSharedLibrary
function.
buildResults = compiler.build.cppSharedLibrary("analyzeData.m", ... OutputDir=".\output", Verbose="on",... AdditionalFiles="P:\MATLAB\work\data\dataInterface.dll");
The interface library dataInterface.dll
must be added as a
dependent file using the AdditionalFiles
name-value
pair.
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. 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 analyzeData.ctf analyzeDatav2.hpp readme.txt
Note
The analyzeDatav2.hpp
header file, which is typically
used for working with strongly typed interfaces, is generated but not used
in this context.
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 into a C++
application, adhere to these guidelines:
Use a
#include
directive to incorporate the C++ header file (.hpp
file) containing the structure definitions 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.
In the
work
folder for this example create a new file namedPassCppStructConsoleApp.cpp
with the following code.IN_PROCESS
ModeIn the application code, you must start MATLAB Runtime in
IN_PROCESS
mode in order to pass C++ structs to MATLAB functions.USING_TYPE_WITH_MATLAB
MacroThe
USING_TYPE_WITH_MATLAB
macro is used to inform MATLAB about the custom C++ types that will be utilized within the integration. The general form of this macro isUSING_TYPE_WITH_MATLAB(namespace::structure_name, "interface_name")
, wherenamespace::structure_name
is the fully qualified name of the C++ structure, andinterface_name
is the name of the interface defined for MATLAB. This setup ensures that MATLAB correctly recognizes and handles these structures during function calls. For instance, in the provided code, the macro is used to map thecppstruct::OutputStruct
,cppstruct::InputStruct
, andcppstruct::FieldStats
types to the interface nameddata
.matlab::cpplib::MATLABLibrary::feval
MethodWhen using the strongly typed interface, you include the generated header file (
.hpp
file) in your application code, allowing you to directly call MATLAB functions defined in the (.ctf
file) from your C++ code. However, when passing C++ structures to deployed MATLAB functions, you cannot call these functions directly. Instead, you must use thematlab::cpplib::MATLABLibrary::feval
method in your C++ code to evaluate and execute the MATLAB functions.Compile and link the application by executing the
mbuild
function at the MATLAB command prompt.mbuild -v PassCppStructConsoleApp.cpp -outdir output\bin
Visual Studio
If you are using Visual Studio for the integration phase, follow the steps in Set Up Microsoft Visual Studio for C++ Development (Windows Only). Additionally, you need to make some changes to ensure your debug build uses the same C/C++ Runtime Library as MATLAB. To do this:
Open Visual Studio and navigate to your project in the Solution Explorer.
Right-click on your project name and select Properties from the context menu.
In the properties window, navigate to Configuration Properties > C/C++ > Preprocessor.
Remove
_DEBUG
from the Preprocessor Definitions list.Navigate to Configuration Properties > C/C++ > Code Generation. Change the Runtime Library setting to Multi-threaded DLL (/MD).
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\PassCppStructConsoleApp.exe
Executing MATLAB function ... Temperatures - Mean: 70.8000, Std: 2.7749, Max: 75.0000 Pressures - Mean: 29.9400, Std: 0.2702, Max: 30.2000
See Also
clibgen.buildInterface
| compiler.build.cppSharedLibrary
| arguments
| matlab::cpplib::MATLABLibrary::feval