For statically allocated arrays, the generated code contains the definition of the array and the size of the array.
For example, consider the MATLAB® function myuniquetol
.
function B = myuniquetol(A, tol) %#codegen A = sort(A); coder.varsize('B', [1 100], [0 1]); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end
The statement coder.varsize('B', [1 100], [0 1])
specifies
that B
is a variable-size array whose first dimension
is fixed at 1 and second dimension can vary up to 100 elements. Without
this statement, B
is a dynamically allocated array.
Generate code for myuniquetol
specifying
that input A
is a variable-size real double vector
whose first dimension is fixed at 1 and second dimension can vary
up to 100 elements.
codegen -config:lib -report myuniquetol -args {coder.typeof(0,[1 100],1),coder.typeof(0)}
In the generated code, the function declaration is:
extern void myuniquetol(const double A_data[], const int A_size[2], double tol, double B_data[], int B_size[2])
The function signature declares the input argument A
and
the output argument B
. A_size
contains
the size of A
. B_size
contains
the size of B
after the call to myuniquetol
.
Use B_size
to determine the number of elements
of B
that you can access after the call to myuniquetol
. B_size[0]
contains
the size of the first dimension. B_size[1]
contains
the size of the second dimension. Therefore, the number of elements
of B
is B_size[0]*B_Size[1]
.
Even though B
has 100
elements
in the C code, only B_size[0]*B_Size[1]
elements
contain valid data.
The following C main function shows how to call myuniquetol
.
void main() { double A[100], B[100]; int A_size[2] = { 1, 100 }; int B_size[2]; int i; for (i = 0; i < 100; i++) { A[i] = (double)1/i; } myuniquetol(A, A_size, 0.1, B, B_size); }
In generated code, MATLAB represents dynamically allocated
data as a structure type called emxArray
. An embeddable
version of the MATLAB mxArray
, the emxArray
is
a family of data types, specialized for all
base types.
typedef struct emxArray_<baseTypedef> { <baseType> *data; int *size; int allocatedSize; int numDimensions; boolean_T canFreeData; } emxArray_<baseTypedef>;
baseTypedef
is the predefined type in rtwtypes.h
corresponding
to baseType
. For example, here is the definition
for an emxArray
of base type double
with
unknown upper bounds:
typedef struct emxArray_real_T { double *data; int *size; int allocatedSize; int numDimensions; boolean_T canFreeData; } emxArray_real_T;
The predefined type corresponding to double
is real_T
.
For more information on the correspondence between built-in data types
and predefined types in rtwtypes.h
, see How MATLAB Coder Infers C/C++ Data Types.
To define two variables, in1
and in2
,
of this type, use this statement:
emxArray_real_T *in1, *in2;
Field | Description |
---|---|
*data | Pointer to data of type <baseType>. |
*size | Pointer to first element of size vector. Length of the vector equals the number of dimensions. |
allocatedSize | Number of elements currently allocated for the array. If the size changes, MATLAB reallocates memory based on the new size. |
numDimensions | Number of dimensions of the size vector, that is, the number of dimensions you can access without crossing into unallocated or unused memory. |
canFreeData | Boolean flag indicating how to deallocate memory:
|
When you generate code that uses variable-size data, the code
generator exports a set of utility functions that you can use to create
and interact with emxArrays
in your generated code.
To call these functions in your main C function, include the generated
header file. For example, when you generate code for function foo
,
include foo_emxAPI.h
in your main C function. For more information, see the "Write a
C Main Function" section in Using Dynamic Memory Allocation for an "Atoms" Simulation.
Note:
The code generator exports |
Function | Arguments | Description |
---|---|---|
emxArray_<baseType> *emxCreateWrapper_<baseType>
(...) | *data num_rows num_cols | Creates a new 2-dimensional emxArray , but
does not allocate it on the heap. Instead uses memory provided by
the user and sets canFreeData to false so
it does not inadvertently free user memory, such as the stack. |
emxArray_<baseType> *emxCreateWrapperND_<baseType>
(...) | *data numDimensions *size | Same as emxCreateWrapper_<baseType> ,
except it creates a new N-dimensional emxArray . |
emxArray_<baseType> *emxCreate_<baseType>
(...) | num_rows num_cols | Creates a new two-dimensional emxArray on
the heap, initialized to zero. All
data elements have the data type specified by <baseType> . |
emxArray_<baseType> *emxCreateND_<baseType>
(...) | numDimensions *size | Same as emxCreate_<baseType> , except
it creates a new N-dimensional emxArray on the
heap. |
void emxInitArray_<baseType> (...) | **emxArray numDimensions | Creates a new empty emxArray on the heap.
All data elements have the data type
specified by <baseType> . |
void emxInitArray_<structType> (...) | *structure | Creates empty emxArray s in a structure. |
void emxDestroyArray_<baseType> (...) | *emxArray | Frees dynamic memory allocated by emxCreate_<baseType> , emxCreateND_<baseType> ,
and emxInitArray_baseType functions. |
void emxDestroyArray_<structType> (...) | *structure | Frees dynamic memory allocated by emxInitArray_<structType> functions. |
By default, when you generate C/C++ source code, static libraries,
dynamic libraries, and executables, MATLAB Coder™ generates an example C/C++
main function. The example main function is a template that can help
you to incorporate generated C/C++ code into your application. If
you generate code that uses dynamically allocated data, the example
main function includes calls to emxArray
utility
functions that create emxArrays
required for this
data. The example main function also initializes emxArray
data
to zero values. For more information, see Incorporate Generated Code Using an Example Main Function.