Generate C++ Executable for Entry-Point System Object in a Namespace
R2026bThis example shows how to use a System object™ in a namespace as an entry point for C++ code generation. The code generator produces a C++ class that you can access directly from your external code. You then create an executable that uses the generated class.
Note
Using a MATLAB® class as an entry point for code generation is a tech preview. This
feature is in active development and might change between the tech preview and the
general release. To enable the feature, enter
enableCodegenForEntryPointClasses at the command line before
launching the MATLAB
Coder™ app, calling the codegen function, or creating a coder.Type object. To provide feedback, email the
development team or participate
in a survey.
Enable Tech Preview
Before you begin, enable code generation for entry-point classes.
enableCodegenForEntryPointClasses
=== Code generation for entry-point classes is ENABLED ===
Create MATLAB Class
This example uses the System object
MyCounter. The public MyCounter class
constructor method defines a MyCounter object with a step size
specified by the public property StepSize.
The MyCounter class implements these protected methods:
stepImpl, which increments the countersetupImpl, which initializes the counterresetImpl, which resets the counter
The System object
step method invokes the stepImpl method.
Save the MyCounter definition in the namespace
+MyNamespace.
classdef MyCounter < matlab.System properties StepSize = 1 end properties (DiscreteState) Count end methods function obj = MyCounter(stepVal) if nargin > 0 obj.StepSize = stepVal; end end end methods (Access = protected) function setupImpl(obj) obj.Count = 0; end function y = stepImpl(obj) obj.Count = obj.Count + obj.StepSize; y = obj.Count; end function resetImpl(obj) obj.Count = 0; end end end
Define coder.ClassSignature Object
Define a coder.ClassSignature object by using the name of the namespace and the
MyCounter class.
classSig = coder.ClassSignature("MyNamespace.MyCounter")classSig =
coder.ClassSignature
1×1 MyNamespace.MyCounter
TypeName: "MyCounter"
Properties: struct with no fields.
Methods: dictionary (string --> cell) with no entries.Add the public constructor method MyCounter to the
classSig object by using the addMethod
method. Do not include the namespace in the name of the method, because MATLAB does not store class methods inside namespaces. Specify that the
constructor method is polymorphic and accepts one or zero arguments.
addMethod(classSig,"MyCounter",{0}); addMethod(classSig,"MyCounter",{})
ans =
coder.ClassSignature
1×1 MyNamespace.MyCounter
TypeName: "MyCounter"
Properties: struct with no fields.
Methods:
MyCounter:
(1) Args: {1×1 double}
(2) Args: {}The code generator creates two coder.FunctionSignature objects that represent the two signatures of
the MyCounter method and adds these objects to the class signature
object.
Add the System object
step method to the coder.ClassSignature object.
Because step can return a variable number of outputs, specify the
Nargout name-value argument when you call
addMethod.
addMethod(classSig,"step",{classSig},Nargout = 1)ans =
coder.ClassSignature
1×1 MyNamespace.MyCounter
TypeName: "MyCounter"
Properties: struct with no fields.
Methods:
MyCounter:
(1) Args: {1×1 double}
(2) Args: {}
step:
Args: {1×1 this}
Nargout: 1Generate MEX Function and Test Generated Class
Generate a MEX function from the entry-point class. By default, calling the
codegen command on an entry-point
class generates a C MEX function with the same name as the MATLAB class in the working folder. Use the -class option
to specify the class object, and use the -lang:c++ option to
generate C++ code.
codegen -lang:c++ -class classSig
Code generation successful.
When you generate a MEX function for an entry-point class, the generated function contains the class and method definitions. To create an instance of the generated class, invoke the class constructor by passing the name of the constructor to the MEX function, followed by the required inputs.
For this example, construct two instances of the generated class, one with the default step size of 1 and one with a step size of 3. Because the class is inside a namespace, call the constructor method by using dot notation.
MyMexSystObject1 = MyNamespace_MyCounter_mex("MyNamespace.MyCounter"); MyMexSystObject3 = MyNamespace_MyCounter_mex("MyNamespace.MyCounter",3);
To test the generated class, call the step method. The objects
increment by the expected amount.
MyMexSystObject1.step
ans = 1
MyMexSystObject1.step
ans = 2
MyMexSystObject3.step
ans = 3
MyMexSystObject3.step
ans = 6
Specify C++ Namespace for Generated Code
You can use the code configuration settings to control how the code generator creates namespaces for the code it generates. See Organize Generated C++ Code into Namespaces.
By default, the code generator produces C++ namespaces for the namespaces in the
MATLAB code. In this example, it stores the code it generates for the
user-written MATLAB code in the C++ namespace MyNamespace. To control
how the code generator partitions the generated C++ code into namespaces, create a
code configuration object for a static library and modify these settings:
To generate C++ code, set the
TargetLangproperty to"C++". See Language.To instruct the code generator to contain the C++ code it generates in the namespace
allCode, set theCppNamespaceproperty to"allCode". See C++ namespace.To instruct the code generator to contain the code it generates for MathWorks® code in the namespace
notMyCode, set theCppNamespaceForMathworksCodeproperty to"notMyCode". See Namespace for MathWorks code.
cfg = coder.config("lib"); cfg.TargetLang = "C++"; cfg.CppNamespace = "allCode"; cfg.CppNamespaceForMathworksCode = "notMyCode";
Generate and Inspect Standalone C++ Code
Generate a C++ static library for the MyCounter class by
passing the classSig object to the codegen
command. Use the -class option to specify the class object, and
use the -config option to specify the code configuration
object.
codegen -config cfg -class classSig
Code generation successful.
Inspect the definition of the MyCounter class in the generated
C++ header file MyNamespace_MyCounter.h.
// Type Definitions
namespace allCode {
namespace MyNamespace {
class MyCounter {
public:
void init(double stepVal);
void init();
double step();
explicit MyCounter(double stepVal);
explicit MyCounter(user_construct_tag_t tag);
MyCounter();
~MyCounter();
private:
void System();
public:
boolean_T tunablePropertyChanged;
int isInitialized;
boolean_T TunablePropsChanged;
double StepSize;
double Count;
private:
boolean_T isSetupComplete;
};
The definition of the MyCounter class is in the namespace
MyNamespace, which is in the namespace
allCode. The code generator produces three constructor
methods:
explicit MyCounter(double stepVal), which maps to the constructor that accepts a double value.explicit MyCounter(user_construct_tag_t tag), which maps to the constructor that accepts zero arguments.MyCounter(), which is the non-initializing constructor.
The external C++ application can interact directly with the public
MyCounter constructors and the public property
StepSize. The init methods and the
non-initializing constructor are internal methods. Do not use internal methods in
your custom C++ code.
The System method performs operations internal to the generated
System object class. The System method uses the public state
members tunablePropertyChanged, isInitialized,
and TunablePropsChanged to manipulate instances of the C++
class.
Inspect the definition of the MyCounter::init method in the
file
MyNamespace_MyCounter.cpp.
void MyCounter::init(double stepVal)
{
System();
notMyCode::matlab::b_system::coder::SystemProp::matlabCodegenNotifyAnyProp(
this);
StepSize = stepVal;
}The init method uses the method
matlabCodegenNotifyAnyProp. Because the code generator produces
the C++ code for this method from MathWorks code, the code generator defines the
matlabCodegenNotifyAnyProp method in the C++ namespace
notMyCode.
Create C++ main Function
When you generate code for an entry-point class, the code generator does not
produce an example main function. To generate an executable that
uses the generated class, you must write main function for your
application.
For example, this C++ main function uses the generated class.
Save this code in the working folder as
main_MyCounter.cpp.
#include "MyNamespace_MyCounter.h"
#include <iostream>
int main(void) {
using namespace allCode;
MyNamespace::MyCounter countStep3{3};
MyNamespace::MyCounter countStepD{user_construct_tag_t{}};
std::cout << "MyCounter with StepSize: " << countStep3.StepSize << std::endl;;
std::cout << "Increment once: " << countStep3.step() << std::endl;
std::cout << "Increment twice: " << countStep3.step() << std::endl;
std::cout << "MyCounter with StepSize: " << countStepD.StepSize << std::endl;;
std::cout << "Increment once: " << countStepD.step() << std::endl;
std::cout << "Increment twice: " << countStepD.step() << std::endl;
return 0;
}This main function creates two instances of the
MyNamespace::MyCounter class:
It uses the constructor that accepts a double value to create
countStep3, which has a step size of three.It uses the constructor that accepts the
user_construct_tag_ttag to createcountStepD, which has the default step size of one.
The main function increments each counter twice and displays
the results.
Generate C++ Executable
Generate a C++ executable by using the codegen command. To
generate executable code, set the OutputType property of the
configuration object to "EXE". See Build
type.
cfg.OutputType = "EXE";Instruct the codegen command to include the
main_MyCounter.cpp source code file by specifying the file
name on the command line. The code generator creates the
MyNamespace_MyCounter executable in the working
folder.
codegen -config cfg -class classSig main_MyCounter.cpp;
Code generation successful.
To run the executable in MATLAB, use the system command. Use the ispc function to choose the appropriate
system command.
if ispc system("MyNamespace_MyCounter.exe") else system("./MyNamespace_MyCounter") end
MyCounter with StepSize: 3
Increment once: 3
Increment twice: 6
MyCounter with StepSize: 1
Increment once: 1
Increment twice: 2
ans =
0See Also
addMethod | codegen | coder.ClassSignature | coder.FunctionSignature