方法生成C代码MATLAB编码器应用程序
在本教程中,您将使用MATLAB®编码器™app为MATLAB函数生成一个静态C库。首先生成的C代码只能接受具有固定预分配大小的输入。然后生成可以接受许多不同大小的输入的C代码。
方法还可以在MATLAB命令行上生成代码codegen
命令。有关此工作流程的教程,请参见在命令行生成C代码.
的MATLAB编码器中不支持AppMATLAB在线™.生成C/ c++代码MATLAB在线,使用codegen
命令。
教程文件
从文件夹中复制教程文件
到本地工作文件夹。在这里,matlabroot
帮助\ \工具箱\编码器\ \欧几里得例子
为MATLAB安装文件夹,例如,matlabroot
C:\Program Files\MATLAB\R2019a
.要将这些文件复制到您的当前文件夹,运行这个MATLAB命令:
拷贝文件(fullfile (matlabroot,“帮助”,“工具箱”,“编码器”,“例子”,“欧几里得”))
euclidean_data.mat
,euclidean.m
,test.m
文件。
MATLAB数据文件
euclidean_data.mat
包含两个数据:三维欧氏空间中的一个点和三维欧氏空间中其他几个点的集合。更具体地说:x
是一个3.
——- - - - - -1
表示三维欧氏空间中一点的列向量。cb
是一个3.
——- - - - - -216
数组中。的每一栏cb
表示三维欧氏空间中的一点。
MATLAB文件
euclidean.m
包含函数欧几里得
实现了核心算法在这个例子中。函数取x
而且cb
作为输入。它计算了之间的欧氏距离x
每一个点cb
并返回这些量:列向量
y_min
等于in的列cb
这代表了最接近的点x
.列向量
y_max
等于in的列cb
这表示离我们最远的点x
.二维向量
idx
它包含了向量的列下标y_min
而且y_max
在cb
.二维向量
距离
包含计算到的最小和最大距离x
.
函数[y_min,y_max,idx,distance] =欧几里得(x,cb)初始化最小距离为到cb第一个元素的距离初始化最大距离为到cb第一个元素的距离idx (1) = 1;idx (2) = 1;距离(1)=规范(x-cb (: 1));距离(2)=规范(x-cb (: 1));求cb中到x距离最小的向量求cb中到x的距离最大的向量为指数= 2:尺寸(cb, 2) d =规范(x-cb(:,指数));如果D <距离(1)距离(1)= Didx(1) =指数;结束如果D >距离(2)距离(2)= D;idx(2) =指数;结束结束输出最小和最大距离向量y_min = cb (:, idx (1));y_max = cb (:, idx (2));结束
MATLAB脚本
test.m
加载数据文件euclidean_data.mat
进入工作区。然后调用函数欧几里得
计算y_min
,y_max
,idx
,距离
.然后,脚本在命令行中显示计算的数量。加载
euclidean_data.mat
是在调用核心算法之前执行的预处理步骤。显示结果是后处理步骤。%负载测试数据负载euclidean_data.mat确定最近和最远的点和相应的距离[y_min,y_max,idx,distance] =欧几里得(x,cb);显示最近点的输出disp (“最近点的坐标是:”);disp (num2str (y_min '));disp ([“最近点的索引为”num2str (idx (1))));disp ([“到最近点的距离是”num2str(距离(1))));disp(换行符);显示最远点的输出disp (“最远点的坐标是:”);disp (num2str (y_max '));disp ([“最远点的索引是”num2str (idx (2))));disp ([“到最远点的距离是”num2str(距离(2))));
提示
可以从MATLAB函数中生成代码MATLAB编码器.不支持从MATLAB脚本生成代码。
使用测试脚本将预处理和后处理步骤从实现核心算法的功能中分离出来。这种做法使您能够轻松重用算法。您可以为实现核心算法的MATLAB函数生成代码。您不需要为测试脚本生成代码。
生成C代码MATLAB函数
运行原始版本MATLAB代码
运行测试脚本test.m
在MATLAB。输出显示y
,idx
,距离
.
最靠近点的坐标为:0.8 0.8 0.4最靠近点的坐标为171最靠近点的距离为0.080374最靠近点的坐标为:0 0 1最靠近点的坐标为6最靠近点的距离为1.2923
使MATLAB适合代码生成的代码
当你输入代码时,MATLAB编辑器中的代码分析器会不断检查你的代码。它报告问题并建议修改,以最大化性能和可维护性。
开放
euclidean.m
在MATLAB编辑器中。MATLAB编辑器右上角的代码分析器消息指示符是绿色的。分析器没有检测到代码中的错误、警告或改进的机会。函数声明之后,添加
% # codegen
指令:函数[y,idx,distance] =欧几里得(x,cb)% # codegen
% # codegen
指令提示代码分析器识别特定于代码生成的警告和错误。代码分析器消息指示器变成红色,表示它检测到代码生成问题。
若要查看警告消息,请将光标移到带下划线的代码片段。警告表明代码生成需要这些变量
idx
而且距离
在下标之前完全定义。出现这些警告是因为代码生成器必须在这些变量第一次出现在代码中时确定它们的大小。要修复此问题,请使用的
函数同时分配和初始化这些数组。初始化最小距离为到cb第一个元素的距离初始化最大距离为到cb第一个元素的距离Idx = ones(1,2);距离= ones(1,2)*norm(x-cb(:,1));
Code Analyzer消息指示器再次变成绿色,表明它没有检测到任何更多的代码生成问题。
有关使用代码分析器的更多信息,请参见使用代码分析器检查代码中的错误和警告.
保存文件。
方法来编译代码MATLAB编码器应用。在这里,编译是指从你的MATLAB代码生成C/ c++代码。
请注意
MATLAB代码的编译是指从MATLAB代码中生成C/ c++代码。在其他上下文中,术语编译可以指C/ c++编译器的操作。
打开MATLAB编码器应用程序和选择源文件
在MATLAB工具条上应用程序选项卡,在代码生成,按MATLAB编码器应用程序图标。应用程序打开选择源文件页面。
在选择源文件页中,输入或选择入口点函数的名称
欧几里得
.一个入口点函数是一个顶级的MATLAB函数,您可以从中生成代码。应用程序用默认名称创建一个项目euclidean.prj
在当前文件夹中。点击下一个去定义输入类型的一步。应用程序在入口点函数上运行代码分析器(在上一步中已经运行过)和代码生成准备工具。代码生成准备工具筛选MATLAB代码中不支持代码生成的特性和函数。如果应用程序发现了问题,它会打开检查代码生成准备情况页,您可以在其中检查和修复问题。在本例中,因为应用程序没有检测到问题,所以它打开定义输入类型页面。有关更多信息,请参见代码生成准备工具.
请注意
代码分析器和代码生成准备工具可能无法检测到所有的代码生成问题。在消除这两个工具检测到的错误或警告之后,用MATLAB编码器以确定您的MATLAB代码是否有其他遵从性问题。
支持C/ c++代码生成的某些MATLAB内置函数和工具箱函数、类和系统对象具有特定的代码生成限制。这些限制和相关的使用注意事项列于扩展功能章节对应的参考页面。有关更多信息,请参见C/ c++代码生成支持的函数和对象.
定义输入类型
因为C使用静态类型,代码生成器必须在代码生成时确定MATLAB文件中所有变量的类、大小和复杂性,也称为编译时.因此,必须指定所有入口点函数输入的属性。要指定输入属性,你可以:
通过提供一个脚本,调用带有示例输入的入口点函数,指示应用程序自动确定输入属性。
直接指定属性。
在本例中,定义输入的属性x
而且cb
,指定测试文件test.m
代码生成器可以使用它自动定义类型:
输入或选择测试文件
test.m
.点击自动定义输入类型.
测试文件,
test.m
,调用入口点函数,欧几里得
,使用预期的输入类型。应用程序确定输入x
是双(3 x1)
而输入cb
是双(3 x216)
.点击下一个去检查运行时问题的一步。
检查运行时问题
的检查运行时问题step从入口点函数生成MEX文件,运行MEX函数并报告问题。MEX函数是生成的代码,可以从MATLAB内部调用。执行此步骤是最佳实践,因为您可以检测和修复在生成的C代码中难以诊断的运行时错误。缺省情况下,MEX功能包括内存完整性检查。这些检查执行数组边界和维度检查。这些检查检测为MATLAB函数生成的代码中内存完整性的违反。有关更多信息,请参见控制运行时检查.
为了将MATLAB代码转换为高效的C/ c++源代码,代码生成器引入了一些优化,在某些情况下,这些优化会导致生成的代码与原始源代码的行为不同。看到生成代码与MATLAB代码的区别.
打开检查运行时问题对话框中,单击检查问题箭头.
在检查运行时问题对话框中,指定一个测试文件或输入使用示例输入调用入口点函数的代码。对于本例,使用test文件
测验
用来定义输入类型的。点击检查问题.
该应用程序生成一个MEX函数。它运行测试脚本
测验
替换对欧几里得
使用对生成的MEX的调用。如果应用程序在MEX函数生成或执行期间检测到问题,它将提供警告和错误消息。单击这些消息可导航到有问题的代码并修复问题。在本例中,应用程序不会检测到问题。默认情况下,应用程序收集行执行计数。这些计数可以帮助您了解测试文件的质量
test.m
锻炼的欧几里得
函数。若要查看行执行计数,单击查看MATLAB行执行计数.应用程序编辑器在代码左侧显示一个用颜色编码的栏。若要在代码上扩展颜色高亮显示,并查看行执行计数,请将光标放在该栏上。特定的绿色表示此代码的行执行计数位于某个范围内。在这种情况下,
为
-loop执行215次。有关如何解释行执行计数和关闭计数收集的信息,请参见收集和查看您的MATLAB代码的行执行计数.点击下一个去生成代码的一步。
请注意
在从MATLAB代码生成独立的C/ c++代码之前,先生成MEX函数。运行生成的MEX函数,并确保它具有与MATLAB函数相同的运行时行为。如果生成的MEX函数产生的答案与MATLAB不同,或者产生错误,在继续独立代码生成之前,必须修复这些问题。否则,生成的独立代码可能不可靠,并且具有未定义的行为。
生成C代码
打开生成对话框中,单击生成箭头.
在生成对话框,设置构建类型来
静态库(.lib)
而且语言使用其他项目生成配置设置的默认值。您可以选择生成MEX函数或其他C/ c++构建类型,而不是生成C静态库。不同的项目设置可用于MEX和C/ c++构建类型。当您在MEX和C/ c++代码生成之间切换时,请验证所选择的设置。
点击生成.
MATLAB编码器生成一个独立的C静态库
欧几里得
在
.工作
\ codegen \ lib \欧几里得
是包含教程文件的文件夹。的MATLAB编码器App表示代码生成成功。它在页面左侧显示源MATLAB文件和生成的输出文件。在变量选项卡,它显示关于MATLAB源变量的信息。在目标生成日志选项卡,它将显示构建日志,包括C/ c++编译器警告和错误。默认情况下,在代码窗口中,应用程序显示C源代码文件,工作
euclidean.c
.要查看另一个文件,请在源代码或输出文件窗格中,单击文件名。点击查看报告以在报表查看器中查看报表。如果代码生成器在代码生成过程中检测到错误或警告,报告将描述问题并提供问题MATLAB代码的链接。有关更多信息,请参见代码生成报告.
点击下一个打开完成工作流程页面。
查看完成工作流页面
的完成工作流程页指示代码生成成功。它提供了项目摘要和生成输出的链接。
比较生成的C代码和原始代码MATLAB代码
要比较生成的C代码与原始的MATLAB代码,请打开C文件,euclidean.c
,以及euclidean.m
在MATLAB编辑器中的文件。
关于生成的C代码的重要信息:
函数签名为:
Void欧几里得(const double x[3], const double cb[648], double y_min[3], double y_max[3], double idx[2], double distance[2])
Const double x[3]
对应于输入x
在你的MATLAB代码中。的大小x
是3.
,它对应于从MATLAB代码生成代码时使用的示例输入的总大小(3 x 1)。Const double cb[648]
对应于输入cb
在你的MATLAB代码中。的大小cb
是648
,它对应于从MATLAB代码生成代码时使用的示例输入的总大小(3 x 216)。在本例中,生成的代码使用一维数组来表示MATLAB代码中的二维数组。生成的代码有四个额外的输入参数:数组
y_min
,y_max
,idx
,距离
.这些数组用于返回输出值。它们对应于输出参数y_min
,y_max
,idx
,距离
在原始的MATLAB代码中。代码生成器保留函数名和注释。如果可能,代码生成器会保留变量名。
请注意
如果你的MATLAB代码中的一个变量被设置为一个常数值,那么它在生成的C代码中就不会作为一个变量出现。相反,生成的C代码包含变量的实际值。
使用嵌入式编码器®,可以在MATLAB代码和生成的C/ c++代码之间进行交互跟踪。看到MATLAB代码与生成的C/ c++代码的交互跟踪(嵌入式编码).
为可变大小的输入生成C代码
你所生成的C函数euclidean.m
只能接受与您在代码生成期间指定的示例输入相同大小的输入。然而,相应的MATLAB函数的输入数组可以是任意大小的。在本部分教程中,您将从euclidean.m
它接受可变大小的输入。
假设你想要的是x
而且cb
在生成的C代码中具有这些属性:
两者的第一个维度
x
而且cb
大小可以变化到3.
.第二维度
x
是固定的,有价值吗1
.第二维度
cb
大小可以变化到216
.
要指定这些输入属性:
在定义输入类型步骤,输入test文件
test.m
并点击自动定义输入类型像以前一样。测试文件调用入口点函数,euclidean.m
,使用预期的输入类型。应用程序确定输入x
是双(3 x1)
而输入cb
是双(3 x216)
.这些类型指定固定大小的输入。单击输入类型规范并编辑它们。方法可以指定可变大小,但不超过指定的限制
:
前缀。例如,:3
意味着相应的维度的大小可以变化到3.
.将类型更改为双(:3 × 1)
为x
而且双倍(:3 x:216)
为cb
.
现在,您可以按照与前面相同的步骤生成代码。中生成的C代码的函数签名euclidean.c
现在写着:
Void欧几里得(const double x_data[], const int x_size[1], const double cb_data[], const int cb_size[2], double y_min_data[], int y_min_size[1], double y_max_data[], int y_max_size[1], double idx[2], double distance[2])
x_data
,cb_data
,y_min_data
,y_max_data
对应输入参数x
而且cb
输出参数y_min
而且y_max
在原始的MATLAB函数。C函数现在接受四个额外的输入参数x_size
,cb_size
,y_min_size
,y_max_size
的大小x_data
,cb_data
,y_min_data
,y_max_data
在运行时。
下一个步骤
目标 | 更多的信息 |
---|---|
了解MATLAB内置函数和工具箱函数、类和系统对象的代码生成支持 |
|
生成c++代码 |
|
生成并修改一个示例C main函数,并使用它构建一个C可执行程序 |
|
将生成的文件打包到压缩文件中 |
|
优化生成代码的执行速度或内存使用情况 |
|
将您的定制C/ c++代码集成到生成的代码中 |
|
了解代码生成报告 |
MATLAB代码与生成的C/ c++代码的交互跟踪(嵌入式编码) |