Generate Class Interface in C++ Code
When you generate C++ code, the code generator produces a C++ function for each entry-point function by default. Alternatively, you can generate a C++ class interface for your entry-point functions. When you generate a class interface, the code generator creates a C++ class with methods that correspond to the entry-point functions.
The class interface has these benefits:
The generated C++ code is more object-oriented.
The class interface packages global and persistent variables as members of the class. Consequently, you can interact with these variables from your custom C++ code.
The code generator produces a class constructor and destructor that perform memory initialization and termination.
Multiple entry-point functions become methods in a single C++ class. This allows you to use a simpler interface to interact with the entry-point functions in the generated C++ code.
You allocate memory for each class instance separately. The methods for each class instance are thread-safe and reentrant. See Understand and Use Reentrant Code.
Comparison Between Class Interface and Function Interface
This table shows how the generated C++ code can differ when you generate a class interface.
| MATLAB® Code | Generate Entry-Point Functions as C++ Functions (default) | Generate a C++ Class Interface With Name
MyMultClass |
|---|---|---|
function out = myMult(a,b) out = a*b; end | The code generator defines C++ function
| The code generator declares C++ class
The code generator defines
C++ method |
To generate C++ code that has a class interface, use one of these approaches:
In a code configuration object, set the
CppInterfaceStyleproperty to"Methods". Specify a name for the generated C++ interface class by using theCppInterfaceClassNameproperty.In the Code Generation Settings dialog box, set Interface style to
Each entry-point function is generated as a method in a C++ class. Specify a name for the generated C++ interface class by using the C++ interface class name parameter.
Example: Generate C++ Code With and Without Class Interface
This example demonstrates the difference between a function interface and a class interface in the generated C++ code.
Examine MATLAB Function
Examine the MATLAB function myEye.
type myEye.mfunction out = myEye(a,b) out = eye(a,b); end
Generate C++ Code Without Class Interface
First, generate C++ code without a class interface.
Generate a static C++ library for the myEye function by using the codegen command with the -config:lib and -lang:c++ options. Use the -args option to specify that the input arguments are scalar doubles and the -d option to generate code in the folder withoutClass.
codegen -config:lib -lang:c++ -d withoutClass myEye -args {0,0}
Code generation successful.
Examine the declaration of the C++ myEye function in the file myEye.h. The generated C++ function corresponds to the MATLAB entry-point function.
file = fullfile("withoutClass","myEye.h"); coder.example.extractLines(file,"// Function","#endif",0,0)
extern void myEye(double a, double b, coder::array<double, 2U> &out);
Generate C++ Code With Class Interface
Next, generate a C++ class interface for the myEye function. First, create a code configuration object for a static library. Then, modify these properties:
To instruct the code generator to generate the entry-point function as a method in a C++ class, set
cfg.CppInterfaceStyleto"Methods". See Interface style.To specify a name for the interface class, set
cfg.CppInterfaceClassNameto"MyClass". See C++ interface class name.
cfg = coder.config("lib"); cfg.CppInterfaceStyle = "Methods"; cfg.CppInterfaceClassName = "MyClass";
Generate a static C++ library by using the codegen command with the -lang:c++ option and specify the code configuration object by using the -config option. Use the -args option to specify that the input arguments are scalar doubles and the -d option to generate code in the folder withClass.
codegen -config cfg -lang:c++ -d withClass myEye -args {0,0}
Code generation successful.
Examine the definition of the C++ class MyClass in the file myClass.h. The C++ class declares the method myEye, which corresponds to the MATLAB entry-point function.
file = fullfile("withClass","MyClass.h"); coder.example.extractLines(file,"// Type","};",0,1)
class MyClass {
public:
MyClass();
~MyClass();
void myEye(double a, double b, coder::array<double, 2U> &out);
};
Example: Generate Class Interface That Uses Global and Persistent Variables
This example shows how the code generator packages the global and persistent members of a MATLAB class into the generated C++ class interface.
Examine and Run MATLAB Function
Examine the MATLAB function countMyCalls. This function uses a global variable and a persistent variable to keep track of how many times it is called.
type countMyCalls.mfunction [p,g] = countMyCalls %#codegen
persistent persistentCounter;
global globalCounter;
if isempty(persistentCounter)
persistentCounter = 0;
end
persistentCounter = persistentCounter+1;
globalCounter = globalCounter+1;
p = persistentCounter;
g = globalCounter;
end
Clear and initialize the global and persistent variables in the MATLAB workspace, and then run the MATLAB function. The variables increment.
clear countMyCalls global globalCounter; globalCounter = 0; [p,g] = countMyCalls
p = 1
g = 1
[p,g] = countMyCalls
p = 2
g = 2
Reset the global and persistent variables.
clear countMyCalls;
globalCounter = 0;Generate C++ Class Interface
To generate a C++ class interface, create a code configuration object for a static library and modify these properties:
To generate C++ code, set
cfg.TargetLangto"C++". See Language.To instruct the code generator to generate methods in a C++ class from the
countMyCallsfunction, setcfg.CppInterfaceStyleto"Methods". See Interface style.To specify a name for the interface class, set
cfg.CppInterfaceClassNameto"MyCounter". See C++ interface class name.
cfg = coder.config("lib"); cfg.TargetLang = "C++"; cfg.CppInterfaceStyle = "Methods"; cfg.CppInterfaceClassName = "MyCounter";
Generate a static C++ library by using the codegen command and specify the code configuration object by using the -config option.
codegen -config cfg countMyCalls
Code generation successful.
Inspect Generated C++ Code
Inspect the declaration of the C++ class interface MyCounter in the file MyCounter.h. The global variable is a public member of the C++ class. You can access this variable from other classes and functions in your custom C++ code. The persistent variable is a private member of the MyCounter class. You can only access it by using methods of the MyCounter class.
file = fullfile("codegen","lib","countMyCalls","MyCounter.h"); coder.example.extractLines(file,"class MyCounter","};",1,1)
class MyCounter {
public:
MyCounter();
~MyCounter();
void countMyCalls(double *p, double *g);
countMyCallsStackData *getStackData();
double globalCounter;
private:
countMyCallsPersistentData pd_;
countMyCallsStackData SD_;
};
Example: Generate Class Interface for Multiple Entry-Point Functions
This example shows how the code generator packages multiple entry-point functions that use global and persistent variables into the generated C++ class interface.
Examine and Test MATLAB Functions
Examine the functions myGlobalAdd, myGlobalMult, and myGlobalExp. Each time you call one of these functions, the function increments a global counter, which tracks how many times any functions is called, and a persistent counter, which tracks how many times each function is called.
type myGlobalAdd.mfunction [sum,p,g] = myGlobalAdd(x,y) %#codegen
persistent thisFunctionCounter;
global globalCounter;
if isempty(thisFunctionCounter)
thisfunctionCounter = 0;
end
thisfunctionCounter = thisfunctionCounter+1;
globalCounter = globalCounter+1;
sum = x+y;
p = thisfunctionCounter;
g = globalCounter;
end
type myGlobalMult.mfunction [product,p,g] = myGlobalMult(x,y) %#codegen
persistent thisFunctionCounter;
global globalCounter;
if isempty(thisFunctionCounter)
thisFunctionCounter = 0;
end
thisFunctionCounter = thisFunctionCounter+1;
globalCounter = globalCounter+1;
product = x*y;
p = thisFunctionCounter;
g = globalCounter;
end
type myGlobalExp.mfunction [power,p,g] = myGlobalExp(x,y) %#codegen
persistent thisFunctionCounter;
global globalCounter;
if isempty(thisFunctionCounter)
thisFunctionCounter = 0;
end
thisFunctionCounter = thisFunctionCounter+1;
globalCounter = globalCounter+1;
power = x^y;
p = thisFunctionCounter;
g = globalCounter;
end
Clear and initialize the global and persistent variables in the MATLAB workspace, and then run the MATLAB functions. The variables increment independently.
clear myGlobalAdd clear myGlobalMult clear myGlobalExp global globalCounter; globalCounter = 0; [result,thisfunc,allfuncs] = myGlobalAdd(4,5)
result = 9
thisfunc = 1
allfuncs = 1
[result,thisfunc,allfuncs] = myGlobalMult(4,5)
result = 20
thisfunc = 1
allfuncs = 2
[result,thisfunc,allfuncs] = myGlobalExp(4,5)
result = 1024
thisfunc = 1
allfuncs = 3
[result,thisfunc,allfuncs] = myGlobalAdd(4,5)
result = 9
thisfunc = 1
allfuncs = 4
Reset the global and persistent variables.
clear myGlobalAdd clear myGlobalMult clear myGlobalExp globalCounter = 0;
Generate C++ Class Interface
To generate a C++ class interface, create a code configuration object for a static library and modify these properties:
To generate C++ code, set
cfg.TargetLangto"C++". See Language.To instruct the code generator to generate methods in a C++ class from the entry-point functions, set
cfg.CppInterfaceStyleto"Methods". See Interface style.To specify a name for the interface class, set
cfg.CppInterfaceClassNameto"MyFunctionTracker". See C++ interface class name.
cfg = coder.config("lib"); cfg.TargetLang = "C++"; cfg.CppInterfaceStyle = "Methods"; cfg.CppInterfaceClassName = "MyFunctionTracker";
Generate a static C++ library with a class interface by using the codegen command and specify the code configuration object by using the -config option. Specify the three entry-point functions and use the -args option to specify that each function takes two scalar doubles as inputs. The code generator produces the generated code in the folder codegen/lib/myGlobalAdd.
codegen -config cfg myGlobalAdd -args {0,0} myGlobalMult -args {0,0} myGlobalExp -args {0,0}
Code generation successful.
Inspect Generated C++ Code
Inspect the declaration of the C++ class interface MyFunctionTracker in the file MyFunctionTracker.h. Each entry-point function is a public method of the class, and the global variable is a public property of the class. You can access the public methods and the global variable from other classes and functions in your custom C++ code. The persistent variable is a private member of the MyFunctionTracker class. You can only access it by using the methods of the MyFunctionTracker class.
file = fullfile("codegen","lib","myGlobalAdd","MyFunctionTracker.h"); coder.example.extractLines(file,"class MyFunctionTracker","};",1,1)
class MyFunctionTracker {
public:
MyFunctionTracker();
~MyFunctionTracker();
void myGlobalAdd(double x, double y, double *sum, double *p, double *g);
void myGlobalMult(double x, double y, double *product, double *p, double *g);
void myGlobalExp(double x, double y, double *power, double *p, double *g);
myGlobalAddStackData *getStackData();
double globalCounter;
private:
myGlobalAddPersistentData pd_;
myGlobalAddStackData SD_;
};
Examine the definition of the MyFunctionTracker::myGlobalMult method in the file MyFunctionTracker.cpp. The function increments the local persistent counter and the global counter.
file = fullfile("codegen","lib","myGlobalAdd","MyFunctionTracker.cpp"); coder.example.extractLines(file,"void MyFunctionTracker::myGlobalMult","}",1,1)
void MyFunctionTracker::myGlobalMult(double x, double y, double *product,
double *p, double *g)
{
pd_.thisFunctionCounter++;
globalCounter++;
*product = x * y;
*p = pd_.thisFunctionCounter;
*g = globalCounter;
}