生成代码和 MATLAB 代码的形式差异
MATLAB® Coder™ 会将动态类型的 MATLAB 代码转换并优化为静态类型的 C/C++ 代码。静态类型语言要求显式声明变量类型,这些类型是在编译时确定的。由生成器进行某些更改和优化后,就能在生成代码中使用 MATLAB 数据类型和功能。有关代码生成支持的数据类型和功能的详细信息,请参阅数据定义和支持 C/C++ 代码生成的 MATLAB 语言功能。
这些更改和优化会使生成代码的形式与 MATLAB 代码不同。由于以下任一原因,生成代码可能无法与您的 MATLAB 代码一一对应:
注意
根据您的源代码,这些情况可能会与此处显示的略有不同。
将 MATLAB 函数映射到 C/C++ 函数
MATLAB Coder 从 MATLAB 代码生成独立的 C/C++ 代码和 MEX 代码。您的 MATLAB 代码中的单个函数可能会在生成的代码中转换为多个函数。MATLAB 代码中的两个或更多个函数也可能成为生成代码中的单个函数体。此过程称为函数内联。默认情况下,代码生成器使用内部启发式方法来确定是否内联您的函数。有关详细信息,请参阅coder.inline
和Control Inlining to Fine-Tune Performance and Readability of Generated Code。
函数输出的表示形式
MATLAB 函数的输出可能成为 C 语言中的返回值,也可能成为传引用输入。MATLAB 代码中的标量输出在生成的代码中被视为返回值。
函数
addOne
具有输入变量x
和输出变量y
。在此示例中,x
的类型为double
。function y = addOne(x) y = x + 1; end
为该代码段生成的代码如下所示:
double addOne(double x) { return x + 1.0; }
函数
addOne
、x
的输入在生成的代码中被视为传值变量。MATLAB 函数的输出由生成的代码中的值返回。对于数组,输出可能是传引用。此处显示的代码片段使用
double
输入x
和数组输出y
。function y = addMat(x) z = [1:100]; y = z + x; end
输出变量
y
在生成代码中转换为传引用数组变量,如下所示:void addMat(double x, double y[100]) { int i; for (i = 0; i < 100; i++) { y[i] = ((double)i + 1.0) + x; } }
对于具有多个输出变量的入口函数,输出可能是生成的代码中的传引用。以下代码段有两个
double
标量输出,即y
和z
,还有一个double
标量输入x
。function [z,y] = splitOne(x) y = x + 1; z = x + 2; end
输出变量
y
和z
在生成的代码中转换为传引用变量:void splitOne(double x, double *z, double *y) { *y = x + 1.0; *z = x + 2.0; }
有关生成代码中入口函数的参数传递行为的详细信息,请参阅Deploy Generated Code。
在生成的代码中删除的常量值
代码中的常量值可能不会保留在生成的代码中。为了优化生成的代码,可能会删除这些值。常量折叠将删除 MATLAB 代码中可能存在的计算,并用结果替换这些计算。有关详细信息,请参阅 常量折叠。
以如下代码片段为例:
function y = removeConst x = ones(10); y = x + 1; end
代码生成器删除常量矩阵 x
以节省内存,并将常量值指定为结果。生成的代码如下所示:
void removeConst(double y[100]) { int i; for (i = 0; i < 100; i++) { y[i] = 2.0; } }
MATLAB 代码中非入口函数的未使用输入或常量输入将从生成代码的函数体中删除。
代码生成器的函数特化可以将函数更改为一个版本,在该版本中,可为函数的特定调用自定义输入类型、大小、复/实性或值。这样做是为了以代码复制为代价产生高效的 C 代码。有关详细信息,请参阅 Specialized Functions or Classes。
访问矩阵元素
在前面的示例中,访问矩阵需要额外的 C/C++ 代码行。10
×10
矩阵在生成的代码中表示为 100 个 double
元素的数组。在这种情况下,使用 for
循环来访问所有数组元素。C/C++ 不支持许多矩阵运算,因此代码生成器将矩阵和矩阵上的运算转换为数组和类似 for
循环的方法来访问这些数组。
数学运算和其他函数调用
生成的代码可能使用标准的 C 库来执行您的 MATLAB 代码中的数学运算或其他函数。有关支持的语言函数列表,请参阅支持 C/C++ 代码生成的 MATLAB 语言功能。
可变大小数组
对于代码生成,数组可以是固定大小,也可以是可变大小。在生成的代码中,可变大小的数组可能以不同格式出现。如果代码生成器可以确定数组的大小,则可以生成固定大小数组的代码。代码生成也适用于具有上界的固定大小数组。在某些情况下,还会生成动态分配的数组。请参阅可变大小数组的代码生成。
固定大小和可变大小数组的代码生成可能会在生成的代码中产生以下变量声明:
double x[10]; // Fixed-size array double y_data[20]; int y_size[2]; // y_data and y_size denote an upper-bounded array emxArrayReal_T *z; // Dynamically allocated array
生成代码中的局部变量
如果您的 MATLAB 代码包含占用大量内存的局部变量,则在生成的代码中,可能将它们声明为局部变量、静态局部变量或在生成的代码中传入您的入口函数的 struct
中的变量。您可以通过控制为生成的代码分配的内存来控制这种变换。请参阅Control Stack Space Usage。
生成代码中的元胞数组
要在生成的代码中实现元胞数组,代码生成器可能会将它们转换为 struct
、静态数组或动态数组。有关详细信息,请参阅 Code Generation for Cell Arrays。
初始化函数和终止函数
代码生成器可能根据需要产生两个内务处理函数,初始化函数和终止函数。您可以在代码生成报告的 Generated Code 选项卡中找到这些函数。初始化函数初始化生成的 C/C++ 入口函数运行的状态。终止函数释放分配的内存并执行其他清理操作。有关详细信息,请参阅Use Generated Initialize and Terminate Functions。