在命令行生成C代码
在本教程中,您将使用MATLAB®编码器™codegen
命令为MATLAB函数生成静态C库。首先生成的C代码只能接受具有固定预分配大小的输入。然后生成可以接受许多不同大小输入的C代码。
方法也可以生成代码MATLAB编码器有关此工作流的教程,请参见使用MATLAB Coder App生成C代码.
教程文件
从文件夹中复制教程文件
到本地工作文件夹。在这里,matlabroot
帮助\ \工具箱\编码器\ \欧几里得例子
为MATLAB的安装文件夹,例如,matlabroot
C:\Program Files\MATLAB\R2019a
.要将这些文件复制到当前文件夹,运行这个MATLAB命令:
拷贝文件(fullfile (matlabroot,“帮助”,“工具箱”,“编码器”,“例子”,“欧几里得”))
euclidean_data.mat
,euclidean.m
,test.m
,build_lib_fixed.m
,build_lib_variable.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] = euclidean(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 < distance(1) distance(1)= D;idx(1) =指数;结束如果D > distance(2) distance(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] = euclidean(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))));
构建脚本
build_lib_fixed.m
而且build_lib_variable.m
包含从MATLAB代码生成静态C库的命令,分别接受固定大小和可变大小的输入。这些脚本的内容将在本教程后面生成C代码时显示。
提示
可以通过使用从MATLAB函数生成代码MATLAB编码器.不支持从MATLAB脚本生成代码。金宝app
使用测试脚本将预处理和后处理步骤与实现核心算法的函数分开。这种实践使您可以轻松地重用算法。为实现核心算法的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代码适合代码生成,您可以使用代码分析器和代码生成准备工具。当你输入代码时,MATLAB编辑器中的代码分析器会不断检查你的代码。它报告问题并建议修改,以最大化性能和可维护性。代码生成准备工具筛选MATLAB代码中不支持代码生成的特性和功能。金宝app
支持C/ c++代码生成的某些MATLAB内置函数和工具箱函数、类和系统对象具有特定的代码生成限制。金宝app中列出了这些限制和相关的使用说明扩展功能相应的参考页的部分。有关更多信息,请参见C/ c++代码生成支持的函数和对象金宝app.
开放
euclidean.m
在MATLAB编辑器中。MATLAB编辑器右上角的代码分析器消息指示器是绿色的。分析器没有检测到代码中的错误、警告或改进机会。函数声明之后,添加
% # codegen
指令:函数[y,idx,distance] =欧几里得(x,cb)% # codegen
% # codegen
指令提示代码分析器识别特定于代码生成的警告和错误。Code Analyzer消息指示器变成红色,表示它已检测到代码生成问题。
若要查看警告消息,请将光标移动到带下划线的代码片段。警告指示代码生成需要这些变量
idx
而且距离
在下标之前完全定义。出现这些警告是因为代码生成器必须在这些变量第一次出现在代码中时确定它们的大小。若要修复此问题,请使用的
函数同时分配和初始化这些数组。初始化最小距离为到cb第一个元素的距离将最大距离初始化为到cb第一个元素的距离Idx = ones(1,2);距离= ones(1,2)*norm(x-cb(:,1));
Code Analyzer消息指示器再次变为绿色,表示它没有检测到任何代码生成问题。
有关使用代码分析器的详细信息,请参见使用代码分析器检查代码中的错误和警告.
保存文件。
要运行代码生成准备工具,请调用
coder.screener
函数从MATLAB命令行。coder.screener (“欧几里得”)
该工具不会检测到任何代码生成问题
欧几里得
.有关更多信息,请参见代码生成准备工具.中不支持代码生成准备工具金宝appMATLAB在线™.
请注意
代码分析器和代码生成准备工具可能无法检测到所有的代码生成问题。在消除这些工具检测到的错误或警告之后,通过使用生成代码MATLAB编码器以确定您的MATLAB代码是否有其他遵从性问题。
方法编译代码MATLAB编码器应用。在这里,编译指从MATLAB代码生成C/ c++代码。
请注意
编译MATLAB代码是指从MATLAB代码生成C/ c++代码。在其他上下文中,术语编译可以指C/ c++编译器的操作。
定义输入类型
因为C使用静态类型,代码生成器必须在代码生成时确定MATLAB文件中所有变量的类、大小和复杂性,也称为编译时.因此,在为文件生成代码时,必须为入口点函数指定所有输入参数的属性。一个入口点函数是一个顶级的MATLAB函数,您可以从中生成代码。
方法生成代码时codegen
命令,使用arg游戏
选项,为入口点函数指定示例输入参数。代码生成器使用此信息来确定输入参数的属性。
在下一步中,使用codegen
命令从入口点函数生成MEX文件欧几里得
.
检查运行时问题
您可以从入口点函数生成一个MEX函数。MEX函数是生成的代码,可以从MATLAB内部调用。运行MEX函数,检查生成的MEX函数与原始MATLAB函数是否具有相同的功能。
执行此步骤是一种最佳实践,因为您可以检测并修复在生成的C代码中难以诊断的运行时错误。缺省情况下,MEX功能包含内存完整性检查功能。这些检查执行数组边界和维数检查。这些检查可以检测为MATLAB函数生成的代码中违反内存完整性的情况。有关更多信息,请参见控制运行时检查.
为了将MATLAB代码转换为高效的C/ c++源代码,代码生成器引入了一些优化,这些优化在某些情况下会导致生成的代码与原始源代码的行为不同。看到生成的代码和MATLAB代码的区别.
生成一个MEX文件
euclidean.m
通过使用codegen
命令。如果需要验证MEX功能,请运行test脚本测验
调用MATLAB函数欧几里得
替换为对生成的MEX函数的调用。codegeneuclidean.marg游戏{x, cb}以及测验
默认情况下,
codegen
生成一个名为euclidean_mex
在当前文件夹中。你可以使用
arg游戏
选项,为入口点函数指定示例输入参数欧几里得
.代码生成器使用此信息来确定输入参数的属性。你可以使用
以及
选项运行测试文件test.m
.此选项替换对的调用欧几里得
在测试文件中调用euclidean_mex
.
输出结果为:
运行测试文件:'test',带有MEX函数'euclidean_mex'。最近点的坐标为:0.8 0.8 0.4最近点的指数为171最近点的距离为0.080374最远点的坐标为:0 0 1最远点的指数为6到最远点的距离为1.2923
欧几里得
.
请注意
在从MATLAB代码生成独立的C/ c++代码之前,先生成一个MEX函数。运行生成的MEX函数,并确保它具有与MATLAB函数相同的运行时行为。如果生成的MEX函数生成的答案与MATLAB不同,或者产生错误,则必须在继续独立代码生成之前修复这些问题。否则,您生成的独立代码可能不可靠,并且具有未定义的行为。
生成C代码
构建脚本build_lib_fixed.m
包含用于生成代码的命令euclidean.m
.
加载测试数据负载euclidean_data.mat生成欧几里得代码。M和密码原。使用测试数据作为示例输入。codegen报告配置:自由euclidean.marg游戏{x, cb}
codegen
读取文件euclidean.m
并将MATLAB代码转换为C代码。的
报告
选项指示codegen
生成代码生成报告,您可以使用该报告调试代码生成问题,并验证MATLAB代码是否适合代码生成。的
配置:自由
选项指示codegen
来生成一个静态C库,而不是生成默认的MEX函数。的
arg游戏
选项指示codegen
为以下内容生成代码euclidean.m
使用示例输入参数的类、大小和复杂性x
而且cb
.
类的适当选项可以选择生成MEX函数或其他C/ c++构建类型,而不是生成C静态库codegen
命令。有关各种代码生成选项的详细信息,请参见codegen
.
运行构建脚本。
MATLAB处理构建文件并输出消息:
代码生成成功:查看报告。
欧几里得
在
.在这里,工作
\ codegen \ lib \欧几里得
是包含教程文件的文件夹。工作
若要在“报表查看器”中查看代码生成报告,请单击查看报告.
如果代码生成器在代码生成过程中检测到错误或警告,则报告将描述问题并提供到有问题的MATLAB代码的链接。看到代码生成报告.
提示
使用构建脚本在命令行生成代码。构建脚本自动执行一系列在命令行上重复执行的MATLAB命令,从而节省时间并消除输入错误。
将生成的C代码与原始代码进行比较MATLAB代码
要将生成的C代码与原始MATLAB代码进行比较,请打开C文件,euclidean.c
,以及euclidean.m
文件在MATLAB编辑器。
关于生成的C代码的重要信息:
函数签名为:
Void euclidean(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
.
方法指定这些输入属性coder.typeof
函数。coder.typeof (A, B, 1)
指定具有相同类和复杂度的可变大小输入一个
和由size向量的相应元素给出的上界B
.使用构建脚本build_lib_variable.m
使用coder.typeof
在生成的C库中指定可变大小输入的属性。
加载测试数据负载euclidean_data.mat%使用编码器。Typeof指定可变大小的输入eg_x =编码器。typeof (x, [3 1], 1);eg_cb =编码器。typeof (cb [216], 1);生成欧几里得代码。M使用编码器。要指定的类型%示例输入的上限codegen报告配置:自由euclidean.marg游戏{eg_x, eg_cb}
现在,您可以按照与以前相同的步骤生成代码。中生成的C代码的函数签名euclidean.c
现在写着:
Void euclidean(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内置函数和工具箱函数、类和系统对象的代码金宝app生成支持 |
|
生成c++代码 |
|
交互式地创建和编辑输入类型 |
使用编码器类型编辑器创建和编辑输入类型 |
生成并修改一个C main函数示例,并使用它来构建一个C可执行程序 |
|
将生成的文件打包到压缩文件中 |
|
优化生成代码的执行速度或内存使用 |
|
将自定义C/ c++代码集成到生成的代码中 |
|
了解代码生成报告 |
MATLAB代码与生成的C/ c++代码的交互跟踪(嵌入式编码) |