Michal Kutil

A Pointer Transfer Between the S-functions

Technology:
Simulink S-function level 2, C++
Tested:
Linux Matlab Version 7.0.4 (R14SP2), Simulink Version 6.2 (R14SP2)
Windows Matlab Version 6.5.1 (R13SP1), Simulink Version 5.1 (R13SP1)
Keywords:
Matlab, Simulin, S-function, cpp, user data type, pointer transfer between S-functions

Here is described S-function example, which transfers a pointer to an object from one Simulink block to others Simulink blocks. Pointer is marked as your own Simulink data type, which is more safety for a data mismatch.

Simulink's schema with example

This example consists from four files. First one (sfun_source.cpp) sends a pointer to a class 'my_class' (defined in the file myclass.h). This class includes one double which is read from the input, but in general it can include something. Third file (sfun_destination.cpp) is receiver, which read the pointer and returns the double number which is inside of the object. Simulink data type is defined in the file datatype_myclass.cpp.

Code Notes

Simulink custom data type registration, consists from three steps (example from datatype_myclass.cpp).

  1. Data type name registration:
    DTypeId data_type_id = ssRegisterDataType(S, "MyClass");
  2. Specify the amount of memory. If you set the size of a custom data type, you must set a size which is same as a size of double data type. This is very significant, because the pointer to 'my_class' must be during transferring retyped to the double data type. If you use a smaller size, than is double size you lost pointer.
    double tmpdouble;
    ssSetDataTypeSize(S, data_type_id, sizeof(tmpdouble));
  3. Specify the value that represents a zero value. There is necessary use as zero representation any instance of your object. Interesting is that your object must include a constructor, which set a value to your variables inside the object. Otherwise you receive error: cannot modify the zero representation of data type 'MyClass'.
    MyClass* var_myclass = new MyClass;
    ssSetDataTypeZero(S, data_type_id, var_myclass);

After user data type registration you can sends the pointer in mdlOutputs callback function:

real_T *y = ssGetOutputPortRealSignal(S,0);
y[0] = (long int)var_myclass;

Important is the second line, where data type pointer to MyClass, is firstly converted to the data type long int, and next automatically to the double (respective to rel_T).

For back conversion to the pointer we can use next commands. In most case placed in the mdlUpdate callback function in others Simulinks blocks.

InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S,0);
MyClass *var_myclass = (MyClass*)((long int)(*u[0]));

You can download this entire example ico. Simulink mdl file with example is there too.

Question and unsolved problems:

If you know the answer to any of these questions, have you got any commentary, or you don't understand something, please send me email to kutilm@fel.cvut.cz.

Note: In this example aren't solved exceptions and other problems which aren't in direct relation to the problem described above.

Thanks to Michal Sojka and Brad Phelan for hints and consultations.

7. July 2005
Michal Kutil ©2000 - 2010