Main Content

Working With mxArray Outputs in Generated Code

R2026b

When an extrinsic function returns an output during MEX execution or MATLAB Function (Simulink) block simulation, the output is an mxArray object, also known as a MATLAB® array. For more information about extrinsic functions, see Using Extrinsic Functions.

Because the MEX function or MATLAB Function block sends the extrinsic function to MATLAB during execution, the code generator cannot determine the type of the MATLAB output during code generation. As a result, code generation supports a limited number of operations for an mxArray object. You can:

  • Assign it to a variable that is not a class property, cell array element, or structure field.

  • Pass it to a function.

  • Return it to MATLAB.

You cannot perform any other operation on an mxArray object. For example, you cannot:

  • Use it in a mathematical expression.

  • Use it as an index or index into it.

  • Output it from a MATLAB Function block to a Simulink® model.

To use the mxArray output of an extrinsic function in unsupported contexts, convert it to a known type. Create a variable with the same type and size as the output of the extrinsic function, then assign the output of the extrinsic function to this variable. If the size of the extrinsic function output at run time or simulation time is incompatible with the size of the assigned variable, the MEX function or MATLAB Function block produces an error. See Resolve Error: Incorrect Size for Expression.

If you pass the mxArray output of an extrinsic function to another function, the code generator treats the function that accepts the mxArray object as extrinsic. Because this behavior can produce many mxArray objects in the generated code, convert an mxArray object to a known type as soon as possible.

Example: Convert mxArray to Double

Consider this function, which uses coder.extrinsic to declare that the user-written function mySquare is extrinsic. Code generation for mxArrayFixedSizeScalarDouble_error fails because code generation does not support using mxArray objects inside expressions.

function out = mxArrayFixedSizeScalarDouble_error(in) %#codegen
coder.extrinsic("mySquare")
squared = mySquare(in);
out = squared + in;
end

The function mySquare returns a double. To resolve the code generation error, define squared as a scalar double before the extrinsic function call.

...
squared = 0;
squared = mySquare(in);
...

Because you assign the output of the extrinsic function to a variable that you pre-define as a double, the code generator converts the mxArray output to a double.

Example: Convert mxArray to Class

Consider this function, which uses coder.extrinsic to declare that the user-written function constructRec and a method of the Rectangle class, getArea, are extrinsic.

function out = mxArrayClass_error(length,width,factor) %#codegen
coder.extrinsic("constructRec","getArea")
recObj = constructRec(length,width);
area1 = getArea(recObj);
recObj.Width = width*factor;
area2 = getArea(recObj);
out = area2-area1;
end

Code generation for mxArrayClass_error fails because the function accesses a property of recObj. Because recObj is an mxArray object, this operation is not supported. In addition, the function uses the mxArray objects area1 and area2 in a mathematical expression.

To resolve the code generation errors, pre-define variables that are the same size and type as those returned by the extrinsic calls.

...
recObj = Rectangle(0,0);
area1 = 0;
area2 = 0;
...

Insert these definitions before the extrinsic function calls. For example:

function out = mxArrayClass_error(length,width,factor) %#codegen
coder.extrinsic("constructRec","getArea")
recObj = Rectangle(0,0);
area1 = 0;
area2 = 0;
recObj = constructRec(length,width);
area1 = getArea(recObj);
recObj.Width = width*factor;
area2 = getArea(recObj);
out = area2-area1;
end

Example: Convert mxArray to Array of Structures

Consider this function, which uses feval to call the user-written function makeStructs extrinsically. Code generation for mxArrayStructs_error fails because code generation does not support indexing into an mxArray.

function out = mxArrayStructs_error(in)
myStructs = feval("makeStructs",in);
myStructs(in).field1 = 0;
out = myStructs;
end

In this example, the function makeStructs returns a 1-by-in array of structures, each with one field named field1. To resolve the code generation error, fully specify the myStructs array by using a structure template and the repmat function before the extrinsic call.

...
myStructTemplate = struct("field1",0);
myStructs = repmat(myStructTemplate,1,in);
myStructs = feval("makeStructs",in);
...

For more information about using structure templates and repmat to generate code for arrays of structures, see Generate Standalone C Code for Array of Structures.

Example: Convert mxArray to Variable-Size Array

Consider this function, which uses coder.extrinsic to specify that the user-written function getArray is extrinsic. Code generation for mxArrayVarSize_error fails because code generation does not support using an mxArray object in an expression.

function out = mxArrayVarSize_error(in)
coder.extrinsic("getArray");
out = getArray(in);
if numel(out) > 100
    out = 0;
end
end

In this example, the function getArray returns a variable-size array of doubles that has a maximum size of 20-by-20. To resolve the code generation error, specify that out is a variable-size array of doubles before the extrinsic call. First, specify the type by assigning out to a double. Then, use coder.varsize to specify that out is variable size and has an upper bound of 20-by-20.

...
out = 0;
coder.varsize("out",[20 20],[true true]);
out = getArray(in);
...

Example: Convert mxArray to Variable-Size String

Consider this function, which uses coder.extrinsic to declare that the user-written function getName is extrinsic. Code generation for mxArrayString_error fails because code generation does not support assigning an mxArray object to a structure field.

function out = mxArrayString_error(index) %#codegen
coder.extrinsic("getName")
name = getName(index);
studentStruct.name = name;
out = studentStruct;
end

The function getName returns a variable-length string. However, code generation does not support using coder.varsize to specify variable-size strings. See Resolve Error: coder.varsize Not Supported for Strings.

To convert the output of this function to a variable-length string, specify name as an empty character vector, then specify that this vector is variable size by using coder.varsize. Insert these statements before the extrinsic function call. Convert the variable-length character vector back to a string when you assign it to the structure field.

...
name = '';
coder.varsize("name")
name = getName(index);
studentStruct.name = string(name);
...

See Resolve Error: coder.varsize Not Supported for Strings.

See Also

| |

Topics