generate c code with class interface
when you generate c code, the software analyzes your matlab® code and generates entry-point c functions corresponding to your entry-point matlab functions. when you generate c code, you can choose to generate entry-point functions as methods in a c class. using this option:
you obtain more object-oriented code.
the code generator produces a class constructor and destructor that automatically perform memory initialization and termination.
you allocate memory for each class instance separately. the methods for each class instance are thread-safe and reentrant.
multiple entry-point functions become methods in a single c class.
you can generate code with a class interface from the command line or from the
matlab
coder™ app. from the command line, use the cppinterfacestyle
and cppinterfaceclassname
configuration parameters. from the app, on
the generate code step, select language as
c , select interface style as
methods, and then specify the c interface class
name.
these examples show the command-line workflow.
generate c code with a class interface
this example shows how the generated c code differs when it uses a class interface.
matlab algorithm
consider a simple matlab function that performs operations on a matrix and outputs the result.
function out = foog %#codegen i = eye(447); out = ones(447)*i 7;
generate c code with and without class interface
to generate c code with a class interface, use the cppinterfacestyle
and cppinterfaceclassname
parameters. store the output in the withclass
folder.
cfg = coder.config('lib'); cfg.gencodeonly = true; cfg.targetlang = 'c '; cfg.cppinterfacestyle = 'methods'; cfg.cppinterfaceclassname = 'myclass'; codegen foog -config cfg -report -d withclass
code generation successful: to view the report, open('withclass/html/report.mldatx')
next, create a new configuration object and generate c code that does not use a class interface.
cfg = coder.config('lib'); cfg.gencodeonly = true; cfg.targetlang = "c "; codegen foog -config cfg -report -d withoutclass
code generation successful: to view the report, open('withoutclass/html/report.mldatx')
inspect the generated example main function. compare the versions with and without the class interface. with the class interface, the main function calls the entry-point function as a class method.
type withclass/examples/main.cpp
class definition and implementation in the generated code
when the code generator produces code for the c interface class, it ensures that the function methods are reentrant. if the function methods use variables that can exceed the local stack memory limit, set by the configuration parameter stackusagemax
, then the code generator produces private data structures for the variables (identifiable by the suffix stackdata
), rather than declaring the variables as static
. static variables persist between function calls and are not reentrant. for information on generating reentrant c code, see .
to explore the generated class implementations, modify the function foog
such that it contains a variable that exceeds the maximum stack usage specified by the configuration parameter stackusagemax
.
function out = foogbig %#codegen i = eye(448); out = ones(448)*i 7;
the default value for stackusagemax
in bytes is:
cfg.stackusagemax
ans = int32 200000
because foobig
uses a variable of 448^2 (200704) elements, and the code generator produces an 8-bit integer array to represent the variable, the default stack usage limit is exceeded by 704 bytes. generate code for foogbig
.
cfg = coder.config('lib','ecoder',false); cfg.gencodeonly = true; cfg.targetlang = 'c '; cfg.cppinterfacestyle = 'methods'; cfg.cppinterfaceclassname = 'mybigclass'; codegen foogbig -config cfg -report -d withbigclass
code generation successful: to view the report, open('withbigclass/html/report.mldatx')
inspect the generated interface class definitions
inspect the class definitions for the foogbig
project and for foog
. the foogbig
class stores variables that can exceed the maximum stack usage in a private class property, whereas the foog
class only creates local variables on the stack.
when you work with a class definition that contains a stackdata
structure, indicating that the class requires data that exceeds the local stack usage limit, then allocate heap memory for the class instance by using new
. see the generated example main file for your generated code for an example.
globals and persistents in a generated c class
when you generate c code with a class interface, then you access globals and persistents as members of the class. this example shows how to interact with globals and persistents in the class.
matlab algorithm
consider a matlab function that keeps count of the number of times you call it with a global and persistent variable.
function [po,go] = countcalls %#codegen % increment persistent & global variable persistent p global g if isempty(p) p = 0; end p = p 1; g = g 1; % set output variables po = double(p); go = double(g);
generate c code with a class interface
for code generation, initialize the global variable in the workspace.
global g;
g = 0;
generate code in the class called countclass
.
cfg = coder.config('lib'); cfg.gencodeonly = true; cfg.targetlang = 'c '; cfg.cppinterfacestyle = 'methods'; cfg.cppinterfaceclassname = "countclass"; codegen countcalls -config cfg -report
code generation successful: to view the report, open('codegen/lib/countcalls/html/report.mldatx')
inspect the class definition
in the generated c code, an initialization function sets the global variable to the value that you specify in the workspace. you can also specify the initial global value with the codegen -globals
syntax.
inspect the code for the class definition in the header file countclass.h
.
type codegen/lib/countcalls/countclass.h
the global variable is a public member of the class. access this variable from your main function as needed. the persistent variable is stored in a private class data structure.
put multiple entry-point functions in the same class
when you generate c code for multiple entry-point functions and use the class interface setting, then each function becomes a public method of the same class. you can use this technique to create a simpler interface to your multiple entry-point function project.
matlab entry-point functions
break the function countcalls
in the previous example into two, so that one function counts the calls with a persistent variable and the other counts the calls with a global variable. inspect the two functions.
function po = countpersistent %#codegen % increment persistent variable persistent p if isempty(p) p = 0; end p = p 1; % set output variable po = double(p);
function go = countglobal %#codegen % increment global variable global g g = g 1; % set output variable go = double(g);
generate c code
use the codegen
command and specify the initial global variable value as an input.
cfg = coder.config('lib'); cfg.gencodeonly = true; cfg.targetlang = 'c '; cfg.cppinterfacestyle = 'methods'; cfg.cppinterfaceclassname = 'countclassmulti'; codegen countglobal countpersistent -config cfg -report -globals {'g',0}
code generation successful: to view the report, open('codegen/lib/countglobal/html/report.mldatx')
inspect the generated code
to see the generated class definition, open countclassmulti.h
. each entry-point function is a public method of the class.
type codegen/lib/countglobal/countclassmulti.h