Customize Generated C++ Class Interfaces

By setting the model configuration parameter Code interface packaging to C++ class, you can generate a C++ class interface to model code. The generated interface encapsulates required model data into C++ class attributes and model entry-point functions into C++ class methods. The benefits of C++ class encapsulation include:

  • Greater control over access to model data

  • Ability to multiply instantiate model classes

  • Easier integration of model code into C++ programming environments

C++ class encapsulation also works for right-click builds of nonvirtual subsystems. (For information on requirements that apply, see Configure C++ Class Interfaces for Nonvirtual Subsystems.)

To generate C++ class interfaces in model code:

  1. Configure your model to use an ERT-based system target file provided by MathWorks®.

  2. In the Configuration Parameters dialog box, set Language to C++.

  3. Optionally, configure related C++ class interface settings for your model code, using a graphical user interface (GUI) or application programming interface (API).

  4. Generate model code and examine the results.

To get started with an example, see Simple Use of C++ Class Control. For more details about configuring C++ class interfaces for model code, see Customize C++ Class Interfaces Using Graphical Interfaces and Customize C++ Class Interfaces Programmatically. For limitations that apply, see C++ Class Interface Control Limitations.

For an example of C++ class code generation, see Customize Interface to Generated C++ Code That Is Called By C Code.

Simple Use of C++ Class Control

This example illustrates a simple use of C++ class code interface packaging. It generates C++ class code interfaces from an example model, without extensive modifications to default settings.

For details about setting C++ class parameters, see the sections that follow this example, beginning with Customize C++ Class Interfaces Using Graphical Interfaces.

To generate C++ class interfaces for a Simulink® model:

  1. Open a model for which you would like to generate C++ class code interfaces. This example uses the model rtwdemo_counter. Save a copy of the model to a writable location.

  2. Configure the model to use an ERT-based system target file provided by MathWorks.

  3. Set model configuration parameter Language to C++. The setting for model configuration parameter Code interface packaging changes to C++ class. Save the model configuration changes by clicking Apply.

    Note

    To immediately generate the default style of C++ class code, without exploring related model configuration options, skip steps 4 to 8.

  4. Open the Interface pane of the Configuration Parameters dialog box and examine the Code interface section. When you select C++ class code interface packaging for your model, additional C++ class interface controls appear in the Code interface section. See Configure C++ Code Interface Parameters for descriptions of these controls. Modify the parameter settings according to your interface requirements.

  5. Open the Configure C++ class interface dialog box by clicking the Configure C++ Class Interface button. Use the dialog box to configure the step method for your generated model class. The dialog box initially displays a view for configuring a Default step method for the model class. In this view, you can specify the model class name, step method name, and namespace for your model.

    See Configure Step Method for Your Model Class for descriptions of these controls.

    If the default interface style meets your needs, skip steps 6 to 8.

  6. If you want root-level model input and output to be arguments on the step method, set Function specification to I/O arguments step method. The dialog box displays a view for configuring an I/O arguments style step method for the model class. See Configure Step Method for Your Model Class for descriptions of the controls.

  7. Click the Get Default Configuration button. A Configure C++ class interface subpane appears. The subpane displays the initial interface configuration for your model. See Passing I/O Arguments for descriptions of the controls.

  8. If you want to configure I/O arguments generated for your model step method, continue modifying and validating the interface until you are satisfied with the step method configuration.Use the dialog box controls to configure I/O argument attributes. For example, in the Configure C++ class interface subpane, in the row for the Input argument, you can change the value of Category from Value to Pointer and change the value of Qualifier from none to const *. The preview updates to reflect your changes. Click the Validate button to validate the modified interface configuration. To save your changes, click Apply and OK.

    If you choose not to configure I/O arguments, click Cancel to exit the dialog box.

  9. Generate code for the model. In the Code view, review the generated code. Observe that required model data is encapsulated into C++ class attributes and model entry-point functions are encapsulated into C++ class methods. For example, select file rtwdemo_counter.h to see the class declaration for the model.

If you configured custom I/O arguments for the model step method (optional step 8), examine the generated code for the step method in rtwdemo_counter.h and rtwdemo_counter.cpp. The arguments should reflect your changes. For example, if you made the suggested changes for the Input argument, the input argument should appear as const int32_T *arg_Input.

Customize C++ Class Interfaces Using Graphical Interfaces

Select C++ Language

To configure a model to generate C++ class interfaces, set the model configuration parameter Language to C++.

This parameter setting:

Configure C++ Code Interface Parameters

When you configure a model for select C++ class code interface packaging, the Interface pane shows parameters that apply to a C++ interface.

  • Multi-instance code error diagnostic

    Specifies the severity level for diagnostics displayed when a model violates requirements for generating multi-instance code.

    • None — Proceed with build without displaying a diagnostic message.

    • Warning — Proceed with build after displaying a warning message.

    • Error (default) — Abort build after displaying an error message.

  • Remove error status field in real-time model data structure

    Specifies whether to omit the error status field from the generated real-time model data structure rtModel (off by default). Selecting this option reduces memory usage.

    Selecting this option can cause the code generator to omit the rtModel data structure from generated code.

  • Include model types in model class

    Includes model type definitions within the class namespace of the model. Model type definitions include:

    • Root-level inports and outports

    • Block inputs and outputs

    • DWork vectors

    • Block parameters and constant parameters

    • Continuous states

    • The real-time model data structure (rtM)

    The generated code reduces the MISRA 7-3-1 violations.

  • Parameter visibility

    Specifies whether to generate the block parameter structure as a public, private, or protected data member of the C++ model class (private by default).

  • Parameter access

    Specifies whether to generate access methods for block parameters for the C++ model class (None by default). You can select noninlined access methods (Method) or inlined access methods (Inlined method).

  • External I/O access

    Specifies whether to generate access methods for root-level I/O signals for the C++ model class (Inlined structure-based method by default). If you want to generate access methods, you have the following options:

    • Generate noninlined or inlined access methods.

    • Generate per-signal or structure-based access methods. You can generate a series of set and get methods on a per-signal basis, or generate just one set method that takes the address of an external input structure as an argument and, for external outputs (if applicable), just one get method that returns a reference to an external output structure. The generated code for structure-based access methods has the following general form:

      class ModelClass {
      ...
         // Root inports set method
         void setExternalInputs(const ExternalInputs* pExternalInputs);
      
         // Root outports get method
         const ExternalOutputs & getExternalOutputs() const;
      }

    This parameter affects generated code only if you are using the default style step method for your model class, not if you are explicitly passing arguments for root-level I/O signals by using an I/O arguments style step method. For more information, see Passing Default Arguments and Passing I/O Arguments.

  • External I/O visibility

    Specifies whether to generate the root-level I/O structure as a public, private, or protected data member of the C++ model class (private by default).

  • Configure C++ Class Interface

    Opens the Configure C++ class interface dialog box, which enables you to configure the step method for your model class. For more information, see Configure Step Method for Your Model Class.

Interface parameters that are related, but are less commonly used, appear under Advanced parameters:

  • Terminate function required

    Specifies whether to generate the model_terminate method (on by default). This function contains model termination code and must be called as part of system shutdown.

  • Combine signal/state structures

    Specifies whether to combine global block signals and global state data into one data structure in the generated code (cleared by default). Selecting this parameter reduces RAM and improves readability of the generated code.

  • Internal data visibility

    Specifies whether to generate internal data structures, such as Block I/O, DWork vectors, Runtime model, Zero-crossings, and continuous states, as public, private, or protected data members of the C++ model class (private by default).

  • Internal data access

    Specifies whether to generate access methods for internal data structures, such as Block I/O, DWork vectors, Runtime model, Zero-crossings, and continuous states, for the C++ model class (None by default). You can select noninlined access methods (Method) or inlined access methods (Inlined method).

  • Generate destructor

    Specifies whether to generate a destructor for the C++ model class (selected by default).

  • Use dynamic memory allocation for model block instantiation

    For a model containing Model blocks, specifies whether generated code must use dynamic memory allocation, during model object registration, to instantiate objects for referenced models configured with a C++ class interface (cleared by default). If you select this parameter, during instantiation of an object for the top model in a model reference hierarchy, the generated code uses the operator new to instantiate objects for referenced models.

    Selecting this parameter frees a parent model from having to maintain information about referenced models beyond its direct children. Clearing this parameter means that a parent model maintains information about its referenced models, including its direct and indirect children.

    • If you select this parameter, a bad_alloc exception might be displayed, per the C++ standard, if an out-of-memory error occurs during the use of new. Provide code to catch and process the bad_alloc exception in case an out-of-memory error occurs for a new call during construction of a top model object.

    • If you select Use dynamic memory allocation for model block instantiation and the base model contains a Model block, the build process might generate copy constructor and assignment operator functions in the private section of the model class. The purpose of the functions is to prevent pointer members within the model class from being copied by other code. For more information, see Model Class Copy Constructor and Assignment Operator.

Configure Step Method for Your Model Class

To configure the step method for your model class, on the Code Generation > Interface pane, click the Configure C++ Class Interface button, which is available when you select C++ class code interface packaging for a model. In the Configure C++ class interface dialog box that appears, configure the step method for your model class in either of two styles:

The Default step method supports single-rate models and multirate models. You can configure the model for single-tasking operation or multi-tasking operation. This method also supports virtual bus crossing boundaries.

The I/O arguments step method supports single-rate models and multirate models. You can configure the model for single-tasking operation.

Passing Default Arguments.  The Configure C++ class interface dialog box initially displays a view for configuring a Default step method for the model class.

  • Step method name

    Allows you to specify a step method name other than the default, step.

  • Class name

    Allows you to specify a model class name other than the default, modelModelClass.

  • Namespace

    Allows you to specify a namespace for the model class. If specified, the namespace is emitted in the generated code for the model class. The Namespace parameter provides a means of scoping C++ model classes. In a model reference hierarchy, you can specify a different namespace for each referenced model.

  • Step function preview

    Displays a preview of the model step function prototype as currently configured. The preview display is dynamically updated after you validate your current configuration.

    The list of step function arguments has an entry for each of the model’s root-level I/O ports. This list does not include model parameter arguments that can appear in the generated code when the model is used as a referenced model. For example, a model sldemo_mdlref_counter_paramargs has an inport with argument name arg_input, an outport with argument name arg_output, and a saturation block whose limits have workspace parameter argument names lower_saturation_limit and upper_saturation_limit.

    The step function preview for this model is:

    sldemo_mdlref_counter_paramargsModelClass :: step ( arg_input, * arg_output )

    The function prototype in the generated code differs from the preview. The prototype in the generated code (with the additional model parameter arguments) is:

    sldemo_mdlref_counter_paramargsModelClass::step (
       real_T arg_input,
       real_T *arg_output,
       real_T rtp_lower_saturation_limit,
       real_T rtp_upper_saturation_limit)
    
  • Validate

    Validates your current model step function configuration. The Validation pane displays the status and an explanation of a failure.

Passing I/O Arguments.  If you select I/O arguments step method from the Function specification menu, the dialog box displays a view for configuring an I/O arguments style step method for the model class.

  • Get Default Configuration

    Click this button to get the initial interface configuration that provides a starting point for further customization.

  • Step function preview

    Displays a preview of the model step function prototype as currently configured. The preview dynamically updates as you make configuration changes.

  • Validate

    Validates your current model step function configuration. The Validation pane displays the status and an explanation of a failure.

When you click Get Default Configuration, the Configure C++ class interface subpane appears in the dialog box, displaying the initial interface configuration. For example:

  • Step method name

    Allows you to specify a step method name other than the default, step.

  • Class name

    Allows you to specify a model class name other than the default, modelModelClass.

  • Namespace

    Allows you to specify a namespace for the model class. If specified, the namespace is emitted in the generated code for the model class. The Namespace parameter provides a means of scoping C++ model classes. In a model reference hierarchy, you can specify a different namespace for each referenced model.

  • Order

    Displays the numerical position of each argument. Use the Up and Down buttons to change argument order.

  • Port Name

    Displays the port name of each argument (not configurable using this dialog box).

  • Port Type

    Displays the port type, Inport or Outport, of each argument (not configurable using this dialog box).

  • Category

    Displays the passing mechanism for each argument. To change the passing mechanism for an argument, select Value, Pointer, or Reference from the argument's Category menu.

  • Argument Name

    Displays the name of each argument. To change an argument name, click in the argument's Argument name field, position the cursor for text entry, and enter the new name.

  • Qualifier

    Displays the const type qualifier for each argument. To change the qualifier for an argument, select an available value from the argument's Qualifier menu. The possible values are:

    • none

    • const (value)

    • const* (value referenced by the pointer)

    • const*const (value referenced by the pointer and the pointer itself)

    • const & (value referenced by the reference)

Tip

When a model includes a referenced model, the const type qualifier for the root input argument of the referenced model's specified step function interface is set to none and the qualifier for the source signal in the referenced model's parent is set to a value other than none, code generation honors the referenced model's interface specification by generating a type cast that discards the const type qualifier from the source signal. To override this behavior, add a const type qualifier to the referenced model.

Use Namespaces to Scope C++ Model Classes

Embedded Coder® provides namespace control for scoping model classes generated using C++ class code interface packaging. In the Configure C++ class interface dialog box, use the Namespace parameter to specify a namespace for a model class. If specified, the namespace is emitted in the generated code for the model class. To scope the C++ model classes in a model reference hierarchy, you can specify a different namespace for each referenced model.

For an example of namespace control, see the example model rtwdemo_cppclass. This model assigns namespaces as follows:

  • TopNS for top-level model rtwdemo_cppclass

  • MiddleNS for referenced model rtwdemo_cppclass_refmid

  • BottomNS for referenced model rtwdemo_cppclass_refbot

If you build the model with its default settings, you can examine the generated header and source files for each model to see where the namespace is emitted. For example, the Namespace setting for the model rtwdemo_cppclass_refmid is shown below, followed by excerpts of the emitted namespace code in the model header and source files.

42   // Class declaration for model rtwdemo_cppclass_refmid
43   namespace MiddleNS {
44     class MiddleClass {
45       // public data and function members
46      public:
47       // Model entry point functions
...
52       // model step function
53       void StepMethod(const real_T *arg_In1, const real_T &arg_In2, real_T
54                       *arg_Out1, real_T *arg_Out2);
...
87     };
88   }
15   #include "rtwdemo_cppclass_refmid.h"
16   #include "rtwdemo_cppclass_refmid_private.h"
17   
18   namespace MiddleNS
19   {
20     // Model step function
21     void MiddleClass::StepMethod(const real_T *arg_In1, const real_T &arg_In2,
22       real_T *arg_Out1, real_T *arg_Out2)
23     {
...
43     }
...
83   }

Configure C++ Class Interfaces for Nonvirtual Subsystems

You can configure C++ class interfaces for right-click builds of nonvirtual subsystems in Simulink models, if the following requirements are met:

  • The model is configured for the C++ language and C++ class code interface packaging.

  • The subsystem is convertible to a Model block using the function Simulink.SubSystem.convertToModelReference. For referenced model conversion requirements, see the Simulink reference page Simulink.SubSystem.convertToModelReference.

To configure C++ class interfaces for a subsystem that meets the requirements:

  1. Open the containing model and select the subsystem block.

  2. Enter the following MATLAB® command:

    RTW.configSubsystemBuild(gcb)

    where gcb is the Simulink function gcb, returning the full block path name of the current block.

    This command opens a subsystem equivalent of the Configure C++ class interface dialog sequence that is described in detail in the preceding section, Configure Step Method for Your Model Class. (For more information about using the MATLAB command, see RTW.configSubsystemBuild.)

  3. Use the Configure C++ class interface dialog boxes to configure C++ class settings for the subsystem.

  4. Right-click the subsystem and select C/C++ Code > Build This Subsystem.

  5. When the subsystem build completes, you can examine the C++ class interfaces in the generated files and the HTML code generation report.

Customize C++ Class Interfaces Programmatically

If you select the Code interface packaging option C++ class for your model, you can use the C++ class interface control functions (listed in C++ Class Interface Control Functions) to programmatically configure the step method for your model class.

Typical uses of these functions include:

  • Create and validate a new step method interface, starting with default configuration information from your Simulink model

    1. Create a model-specific C++ class interface with obj = RTW.ModelCPPDefaultClass or obj = RTW.ModelCPPArgsClass, where obj returns a handle to an newly created, empty C++ class interface.

    2. Attach the C++ class interface to your loaded ERT-based Simulink model using attachToModel.

    3. Get default C++ class interface configuration information from your model using getDefaultConf.

    4. Use the Get and Set functions listed in C++ Class Interface Control Functions to test or reset the model class name and model step method name. Additionally, if you are using the I/O arguments style step method, you can test and reset argument names, argument positions, argument categories, and argument type qualifiers.

    5. Validate the C++ class interface using runValidation. (If validation fails, use the error message information thatrunValidation returns to address the issues.)

    6. Save your model and then generate code using the rtwbuild function.

  • Modify and validate an existing step method interface for a Simulink model

    1. Get the handle to an existing model-specific C++ class interface that is attached to your loaded ERT-based Simulink model using obj = RTW.getClassInterfaceSpecification(modelName), where modelName is a character vector specifying the name of a loaded ERT-based Simulink model, and obj returns a handle to a C++ class interface attached to the specified model. If the model does not have an attached C++ class interface configuration, the function returns [].

    2. Use the Get and Set functions listed in C++ Class Interface Control Functions to test or reset the model class name and model step method name. Additionally, if the returned interface uses the I/O arguments style step method, you can test and reset argument names, argument positions, argument categories, and argument type qualifiers.

    3. Validate the C++ class interface using runValidation. (If validation fails, use the error message information that runValidation returns to address the issues.)

    4. Save your model and then generate code using the rtwbuild function.

You should not use the same model-specific C++ class interface control object across multiple models. If you do, changes that you make to the step method configuration in one model propagate to other models, which is usually not desirable.

C++ Class Interface Control Functions

FunctionDescription
attachToModelAttach model-specific C++ class interface to loaded ERT-based Simulink model
getArgCategoryGet argument category for Simulink model port from model-specific C++ class interface
getArgNameGet argument name for Simulink model port from model-specific C++ class interface
getArgPositionGet argument position for Simulink model port from model-specific C++ class interface
getArgQualifierGet argument type qualifier for Simulink model port from model-specific C++ class interface
getClassNameGet class name from model-specific C++ class interface
getDefaultConfGet default configuration information for model-specific C++ class interface from Simulink model to which it is attached
getNamespaceGet namespace from model-specific C++ class interface
getNumArgsGet number of step method arguments from model-specific C++ class interface
getStepMethodNameGet step method name from model-specific C++ class interface
getPreviewGet preview of model-specific C++ class interface step function prototype
RTW.configSubsystemBuildOpen GUI to configure C function prototype or C++ class interface for right-click build of specified subsystem
RTW.getClassInterfaceSpecificationGet handle to model-specific C++ class interface control object
runValidationValidate model-specific C++ class interface against Simulink model to which it is attached
setArgCategorySet argument category for Simulink model port in model-specific C++ class interface
setArgNameSet argument name for Simulink model port in model-specific C++ class interface
setArgPositionSet argument position for Simulink model port in model-specific C++ class interface
setArgQualifierSet argument type qualifier for Simulink model port in model-specific C++ class interface
setClassNameSet class name in model-specific C++ class interface
setNamespaceSet namespace in model-specific C++ class interface
setStepMethodNameSet step method name in model-specific C++ class interface

Configure Step Method for Model Class

The following sample MATLAB script configures the step method for the rtwdemo_counter model class, using the C++ Class Interface Control Functions.

%% Open the rtwdemo_counter model
rtwdemo_counter

%% Select ert.tlc as the System Target File for the model
set_param(gcs,'SystemTargetFile','ert.tlc')

%% Select C++ as the target language for the model
set_param(gcs,'TargetLang','C++')

%% Set required option for I/O arguments style step method (cmd off = GUI on)
set_param(gcs,'ZeroExternalMemoryAtStartup','off')

%% Create a C++ class interface using an I/O arguments style step method
a=RTW.ModelCPPArgsClass

%% Attach the C++ class interface to the model
attachToModel(a,gcs)

%% Get the default C++ class interface configuration from the model
getDefaultConf(a)

%% Move the Output port argument from position 2 to position 1
setArgPosition(a,'Output',1)

%% Reset the model step method name from step to StepMethod
setStepMethodName(a,'StepMethod')

%% Change the Input port argument name, category, and qualifier
setArgName(a,'Input','inputArg')
setArgCategory(a,'Input','Pointer')
setArgQualifier(a,'Input','const *')

%% Validate the function prototype against the model
[status,message]=runValidation(a)

%% if validation succeeded, generate code and build
if status
    rtwbuild(gcs)
end

Model Class Copy Constructor and Assignment Operator

Code generation automatically adds a copy constructor and an assignment operator to C++ class declarations when required to securely handle pointer members. The constructor and operator are added as private member functions when both of the following conditions exist:

Under these conditions, the software generates a private copy constructor and assignment operator to prevent pointer members within the model class from being copied by other code.

To prevent generation of these functions, consider clearing the parameter Use dynamic memory allocation for model block instantiation.

The code excerpt below shows generated model.h code for a model class that has a pointer member. (Look for instances of MiddleClass_ptr). The copy constructor and assignment operator declarations are shown in bold.

class MiddleClass;    // class forward declaration for <S1>/Bottom model instance
typedef MiddleClass* MiddleClass_ptr;
...

// Class declaration for model cppclass_top
class Top {
...
  // private data and function members
 private:
  // Block signals
  BlockIO_cppclass_top cppclass_top_B;

  // Block states
  D_Work_cppclass_top cppclass_top_DWork;

  // Real-Time Model
  RT_MODEL_cppclass_top cppclass_top_M;

  // private member function(s) for subsystem '<Root>/Subsystem'
  void cppclass_top_Subsystem_Init();
  void cppclass_top_Subsystem_Start();
  void cppclass_top_Subsystem();

  //Copy Constructor
  Top(const Top &rhs);

  //Assignment Operator
  Top& operator= (const Top &rhs);

  // model instance variable for '<S1>/Bottom model instance'
  MiddleClass_ptr Bottom_model_instanceMDLOBJ1;
};

C++ Class Interface Control Limitations

  • If a model has a custom model step function for which a scalar output is passed by value and is updated in a conditionally executed context, configure the output to be passed by pointer. In the model Configure C++ class interface dialog box, set Category to Pointer. Examples of a conditionally executed context include:

    • Output has a slower sample time than the fundamental rate of the model when the model is used as a referenced model.

    • Conditionally executed subsystem modifies the output.

    • S-function modifies the output.

    • Hit Crossing block modifies the output.

    • Rate Transition block modifies the output.

  • The C++ class value for model configuration parameter Code interface packaging does not support some Simulink model configuration parameters. Selecting C++ class disables these parameters:

    • Identifier format control subpane on the Identifiers pane

    • File customization template parameter on the Templates pane

      The code and data templates on the Templates pane are supported for C++ class code generation. However, the following template file features that are supported for other language selections are not supported for C++ class generated code:

      • Free-form text outside template sections

      • Custom tokens

      • TLC commands (<! > tokens)

    • Global data placement subpane on the Code Placement pane

    Selecting C++ class also disables the Code Mappings editor (see Configure Default C Code Generation for Categories of Data Elements and Functions). You cannot apply default storage classes, memory sections, or function templates to the model.

  • Among the data exchange interfaces available on the Interface pane of the Configuration Parameters dialog box, only the C API interface is supported for C++ class code generation. If you select External mode or ASAP2 interface, code generation fails with a validation error.

  • The I/O arguments style of step method specification supports single-rate models and multirate single-tasking models, but not multirate multitasking models.

  • If you have a Stateflow® license, for a Stateflow chart that resides in a root model configured to use the I/O arguments step method function specification, and that uses a model root inport value or calls a subsystem that uses a model root inport value, do one of the following to generate code:

    • In the Stateflow chart, clear the Execute (enter) Chart At Initialization check box.

    • Insert a Simulink Signal Conversion block immediately after the root inport. In the Signal Conversion block parameters dialog box, select Exclude this block from 'Block reduction' optimization.

  • If a model root inport value connects to a Simscape™ conversion block, insert a Simulink Signal Conversion block between the root inport and the Simscape conversion block. In the Signal Conversion block parameters dialog box, select Exclude this block from 'Block reduction' optimization.

  • When building a referenced model that is configured to generate a C++ class interface:

    • Do not use a C++ class interface in cases when a referenced model cannot have a combined output/update function. Cases include a model that has a continuous sample time or saves states.

    • Do not use virtual buses as inputs or outputs to the referenced model when the referenced model uses the I/O arguments step method. When bus signals cross referenced model boundaries, either use nonvirtual buses or use the Default step method.

  • If the C++ encapsulation interface is not the default, the value is ignored for the Pass fixed-size scalar root inputs by value for code generation parameter. For more information, see Pass fixed-size scalar root inputs by value for code generation.

Customize Interface to Generated C++ Code That Is Called By C Code

Customize the interface of C++ code that you generate from a model and want to call from C or C++ code. To call the C++ code from C code, you encapsulate the C++ class interface in the generated code.

Configure a Model with Custom C++ Encapsulation Interface

If starting with a new model:

  1. Create a model with at least one inport and at least one outport.

  2. Open the Embedded Coder app.

  3. Set model configuration parameter Language to C++.

  4. Set model configuration parameter Code interface packaging to C++ class.

  5. In the Model Configuration Parameters dialog box, on the Code Generation > Interface pane, click Configure C++ Class Interface. Customize the interface as needed. See Customize Generated C++ Class Interfaces.

About C++ Encapsulation Interfaces

A generated C++ class encapsulates model data and methods. Using Embedded Coder®, the encapsulation interface is configurable through model-neutral configuration parameters and model-specific configurations. The interface supports two styles of model step method interfaces: default step method and I/O arguments step method. Use the I/O arguments style interface to customize the step method prototype. Use the default step method style interface to achieve the maximized supported feature set including virtual buses across model boundaries and a multitasking interface.

open_system('rtwdemo_cppclass');

Generate Code

  1. Open the example model rtwdemo_cppclass.

  2. Save a copy of the model to a writable location.

  3. Open the Embedded Coder app.

  4. Generate code.

  5. Examine the generated source code. Minimally, review the customized model step and initialization classes ModelClass::step_method and ModelClass::initialize in file rtwdemo_cppclass.cpp.

  6. View the interface configuration. In the model, double-click the yellow button labeled View Interface Configuration. Alternatively, in the Model Configuration Parameters dialog box on the Code Generation > Interface pane, click Configure C++ Class Interface. Observe the customized arguments for the step function and how they relate to the generated code.

Change to Default Arguments and Rebuild Model

If starting with a new model, populate the initial configuration for the C++ class interface.

  1. In the Model Interface dialog box, click Get Default Configuration.

  2. Close the Model Interface dialog box.

  3. Close the Model Configuration Parameters dialog box.

  4. Generate code.

  5. Use the code generation report to inspect the customized model step and initialization classes ModelClass::step_method and ModelClass::initialize inside the file rtwdemo_cppclass.cpp. Observe the default arguments for the step function and how these relate to the generated code.

Apply Custom Arguments and Rebuild Model

  1. In the model, double-click the yellow button labeled View Interface Configuration. Alternatively, Model Configuration Parameters dialog box, in the Code Generation > Interface pane, click Configure C++ Class Interface.

  2. In the Confgiure C++ class interface dialog box, move Port Name Out1 to the top of the order and set its Category to Value.

  3. Close the Configure C++ class interface dialog box.

  4. Close the Model Configuration Parameters dialog box.

  5. Generate code.

  6. In the generated file rtwdemo_cppclass.cpp, inspect the customized model step and initialization classes ModelClass::step_method and ModelClass::initialize. Observe that the custom arguments appear in the generated code.

Compare Default Interface (Maximum Support) with I/O Arguments Interface

The rtwdemo_cppclass model provides buttons to toggle the function specification for the C++ class interface between the default step method (in multitasking mode) and the I/O arguments step method.

  1. Configure the function specification for the default step method by double-clicking the yellow button labeled Use Default Interface in MultiTasking Mode.

  2. Generate code.

  3. In the generated code, inspect the model step and initialization classes.

  4. Configure the function specification for the I/O arguments step method by double-clicking the yellow button labeled Use I/O Arguments Interface.

  5. Generate code.

  6. In the generated code, inspect the model step and initialization classes.

Apply C++ Class Interface with Referenced Models

The rtwdemo_cppclass_refmid model is a referenced model in example model rtwdemo_cppclass. That referenced model shows how to generate a customizable C++ class interface to generated code for a referenced model in a model reference hierarchy.

  1. Open model rtwdemo_cppclass_refmid.

  2. Open the Embedded Coder app.

  3. Double-click the Subsystem_with_MdlRef_blks block. Then, double-click the middle_instance_1 block.

  4. View the interface configuration in the rtwdemo_cppclass_refmid model. Double-click the yellow button labeled View Interface Configuration. Alternatively, in the Model Configuration Parameters dialog box, on the Code Generation > Interface pane, click Configure C++ Class Interface. Observe that the configuration for the class interface for the referenced model differs from the class interface for the top model (for example, the namespace differs).

open_system('rtwdemo_cppclass_refmid');

Apply Mixed C/C++ Interface Styles in Model Reference Hierarchy

The rtwdemo_cppclass_refc model is a referenced model in the example model rtwdemo_cppclass. That referenced model shows how to use mixed interface styles within a model reference hierarchy. The model uses the C code interface style (compiled with a C++ compiler), while the other models in the same model hierarchy use C++ class interfaces.

  1. Open model rtwdemo_cppclass.

  2. Double-click the Subsystem_with_MdlRef_blks block. Then, double-click the ref_c_instance block.

  3. Open the Embedded Coder app. A dialog box appears asking whether you want to generate code for the top model rtwdemo_cppclass or for the active model rtwdemo_cppclass_refc.

  4. Click the Open active model as top button.

  5. In the Simulink Editor window that opens for model rtwdemo_cppclass_refc, open the Embedded Coder app.

  6. Check the setting of model configuration parameter Code interface packaging. It is set to Nonreusable function (for a C function prototype). Then, close the Model Configuration Parameters dialog box.

  7. Click the Code Mappings - C tab.

  8. In the Code Mappings editor, click the Functions tab.

  9. Click the Update Code Mappings button.

  10. In the table, view the function prototype preview for the step function.

  11. Close the model.

open_system('rtwdemo_cppclass_refc');

More About

For more detail and limitations, see Customize Generated C++ Class Interfaces in the Embedded Coder® documentation.