Main Content

Interface with C++ Classes Using C Function Block

You can use code that you specify in a C Function block to interface directly with C++ classes defined in your custom code.

  • Instantiate an object of a C++ class defined in your custom code.

  • Read and write to public data members of the class object.

  • Call public class methods (class member functions) of the object.

This example demonstrates the use of a C Function block with C++ classes.

Create Source Code Files

Before introducing your custom code, select C++ as the custom code language. In the Model Configuration Parameters, on the Simulation Target pane, set Language to C++.

Next, create the header and source files. Create a header file named adder.h that defines a C++ class adder and its methods.

#ifndef _ADDER_CPP_
#define _ADDER_CPP_

class adder {
private:
    int int_state;
public:
    adder();
    adder(int init_value);
    int add_one(int increment);
    int get_val();
};



#endif /* _ADDER_CPP_ */

Implement the class and its methods in a source file. Create the source file, adder.cpp.

#include "adder.h"

adder::adder()
{
    int_state = 0;
}

adder::adder(int init_value)
{
    int_state = init_value;
}

int adder::add_one(int increment)
{
    int_state += increment;
    return int_state;
}

int adder::get_val()
{
    return int_state;
}

Configure the C Function Block

To instantiate an object of a C++ class defined in the custom code in your model:

  1. Add a C Function block to the model.

  2. Double-click the C Function block to open it.

  3. Define the header and source files:

    1. Click the Configure custom code settings button to open the Configuration Parameters window. In the Simulation Target pane, in the Code information tab, under Include headers, define the header file by entering #include "adder.h".

    2. In the Code Information tab, under Source files, define the source file by entering adder.cpp.

    For more information, see Enter the External Code Into Simulink.

  4. Define the class object. In the block dialog, in the Symbols table, click Add to define a symbol.

  5. Specify the symbol properties. Set the Scope of the symbol to Persistent, set the name of the object in the Name column, set the symbol Type by using the following format:

    Class: <ClassName>

For example, this Symbols table instantiates an object of the adder class named obj. The int_state property of obj is initialized with the default value of zero.

Excerpt of C Function block dialog, showing Symbols table with symbol named "obj" with Persistent scope and Type "Class: adder".

To pass arguments to the class constructor, enclose those arguments in parentheses, separated by commas, following the symbol name in the Name field.

ObjectName(Argument1,Argument2,...)
You can use literal constants as well as expressions with Parameter and Constant symbols defined in the Symbols table for the argument specification. Such expressions can use C syntax, including expressions like &p and p[0], where p is a Parameter or Constant symbol. Overloaded class constructors are supported.

For example, this Symbols table instantiates an object of the adder class named obj, and initializes the int_state property of the object with the value of 10 by passing that value to the constructor.

Excerpt of C Function block dialog, showing Symbols table containing a Persistent scope symbol with Type "Class: adder". The Name field is highlighted and contains "obj(10)".

Simulink® creates the object at the start of simulation and destroys the object when simulation ends. During simulation, the object is cached in the block as a block state like other Persistent symbols. You cannot explicitly call the class constructor or destructor from the block.

You can use the Output Code and other code in the block to read and write to public data members of the class object and to call public class methods of the object. Overloaded methods and operators are supported, as are static methods. Default arguments for class methods are supported if they are specified in the header file that defines the class.

Use Start Code or Initialize Conditions Code to initialize data members and Terminate Code to call cleanup methods. The class object is created before the Start Code executes and is destroyed after the Terminate Code executes. To access properties and methods, use dot notation.

PropertyValue = ClassObjectName.PropertyName;
ReturnValue = ClassObjectName.MethodName(Arguments);
In the Output Code, the block invokes the add_one method of obj. The block passes the block input as an argument to the method and sends the return value to the block output.

Block dialog of C Function block showing code in Output Code field.

If a class constructor or other class method receives multidimensional array data from Simulink or passes such data to Simulink, you must specify the correct array layout to achieve the intended results, as for any other custom code function. See N-D Array Handling. To indicate the array layout of a class method in the dialog box for Exception by function, for the Function Name, use the syntax ClassName::MethodName.

Array Layout for Custom Code Functions dialog. Three function names are listed, all starting with "myClass::".

Limitations

The C Function block cannot be used to directly access all C++ classes. These types of classes are not supported:

  • Template classes

  • Classes that are inside of a namespace

  • Standard Template Library (STL) containers

  • Classes with private constructors and destructors

In such cases, you can access C++ class data members and methods indirectly by writing and calling a C-style wrapper function. For an example, see Call C++ Class Methods Using a C-style Wrapper Function From a C Function Block.

Expressions used for constructor arguments are limited to literal constants and Parameter and Constant symbols. Such expressions may not call other functions or access global variables.

The C Function block cannot call overloaded functions that are not class methods.

These actions are not supported in the code in the C Function block:

  • Copying and assigning a class object

  • Passing a class object to a function or method, either by value or by reference

  • Explicitly calling a class constructor or destructor

  • Defining a class

  • Accessing class static data members

  • Accessing multidimensional data members of a class

Related Topics