主要内容

生成C代码使用MATLAB编码器应用程序

在本教程中,您将使用MATLAB®编码器™应用程序生成一个MATLAB函数的静态C库。首先生成C代码,它只能接受具有固定预先分配大小的输入。然后生成可以接受许多不同大小输入的C代码。

控件也可以在MATLAB命令行中生成代码codegen命令。有关此工作流的教程,请参见在命令行生成C代码

MATLAB编码器应用程序不支持金宝appMATLAB在线™.生成C/ c++代码MATLAB在线,可以使用codegen命令。

教程文件

从文件夹中复制教程文件matlabroot帮助\ \工具箱\编码器\ \欧几里得例子到本地工作文件夹。在这里,matlabroot是MATLAB安装文件夹,例如,C:\Program Files\MATLAB\R2019a.要将这些文件复制到当前文件夹,运行MATLAB命令:

拷贝文件(fullfile (matlabroot,“帮助”“工具箱”“编码器”“例子”“欧几里得”))
本地工作文件夹不能为私有文件夹或@文件夹。本教程使用euclidean_data.mateuclidean.m,test.m文件。

  • MATLAB数据文件euclidean_data.mat包含两部分数据:三维欧几里得空间中的一个点和三维欧几里得空间中其他几个点的集合。更具体地说:

    • x是一个3.——- - - - - -1表示三维欧几里得空间中的一点的列向量。

    • cb是一个3.——- - - - - -216数组中。每一列中cb表示三维欧几里得空间中的一点。

  • MATLAB文件euclidean.m包含的功能欧几里得实现核心算法在这个例子中。的函数xcb作为输入。它计算的是欧氏距离x每个点cb然后返回这些量:

    • 列向量y_min,它等于列cb这表示最接近的点x

    • 列向量y_max,它等于列cb这表示距离最远的点x

    • 二维向量idx它包含向量的列指标y_miny_maxcb

    • 二维向量距离包含了计算到的最小距离和最大距离x

    函数[y_min, y_max idx,距离]=欧几里得(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(:,指数));如果距离(1)= D;idx(1) =指数;结束如果D >距离(2)距离(2)= D;idx(2) =指数;结束结束%输出最小和最大距离向量y_min = cb (:, idx (1));y_max = cb (:, idx (2));结束
  • MATLAB脚本test.m加载数据文件euclidean_data.mat进入工作区。然后调用该函数欧几里得计算y_miny_maxidx,距离.然后脚本在命令行显示计算的数量。

    加载euclidean_data.mat是在调用核心算法之前执行的预处理步骤。显示结果是后处理步骤。

    负载试验数据负载euclidean_data.mat%确定最近和最远的点和相应的距离[y_min, y_max idx,距离]=欧几里得(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脚本生成代码。金宝app

使用测试脚本将预处理和后处理步骤从实现核心算法的函数中分离出来。这种做法使您能够轻松地重用算法。您可以为实现核心算法的MATLAB函数生成代码。您不为测试脚本生成代码。

生成C代码MATLAB函数

运行原MATLAB代码

运行测试脚本test.m在MATLAB。输出显示yidx,距离

最近点坐标为:0.8 0.8 0.4最近点指数为171到最近点的距离为0.080374最远点坐标为:0 0 1最远点指数为6到最远点的距离为1.2923

使MATLAB适合代码生成的代码

当你输入代码时,MATLAB编辑器中的代码分析器会不断地检查你的代码。它报告问题并建议修改,以最大限度地提高性能和可维护性。

  1. 开放euclidean.m在MATLAB编辑器中。MATLAB Editor右上角的Code Analyzer消息指示器是绿色的。分析器没有检测到代码中的错误、警告或改进机会。

  2. 在函数声明之后,添加% # codegen指令:

    函数[y, idx,距离]=欧几里得(x, cb)% # codegen
    % # codegen指令提示代码分析器识别特定于代码生成的警告和错误。

    Code Analyzer消息指示器变为红色,表明它已检测到代码生成问题。

  3. 若要查看警告消息,请将光标移动到带下划线的代码片段。警告表明代码生成需要这些变量idx距离在下标之前完全定义。出现这些警告是因为代码生成器必须在这些变量第一次出现在代码中时确定它们的大小。要修复此问题,请使用函数同时分配和初始化这些数组。

    %初始化最小距离为cb的第一个元素的距离%初始化最大距离为cb的第一个元素的距离idx = 1(1、2);距离= 1(1、2)*规范(x-cb (: 1));

    Code Analyzer消息指示器再次变为绿色,表明它不再检测到任何代码生成问题。

    有关使用代码分析器的更多信息,请参见检查代码中的错误和警告

  4. 保存文件。

    现在可以使用MATLAB编码器应用。在这里,编译指的是从MATLAB代码生成C/ c++代码。

请注意

MATLAB代码的编译是指从MATLAB代码中生成C/ c++代码。在其他情况下,术语编译可以指C/ c++编译器的操作。

打开MATLAB编码器应用程序和选择源文件

  1. 基于MATLAB的工具条应用程序选项卡,在代码生成,单击MATLAB编码器应用程序图标。应用程序打开选择源文件页面。

  2. 选择源文件页,输入或选择入口点函数的名称欧几里得.一个入口点函数是用于生成代码的顶级MATLAB函数。应用程序创建一个默认名称的项目euclidean.prj在当前文件夹中。

  3. 点击下一个去…定义输入类型的一步。应用程序在入口点函数上运行代码分析器(你已经在上一步中运行了)和代码生成准备工具。代码生成准备工具会筛选MATLAB代码中不支持代码生成的特性和函数。金宝app如果应用程序发现问题,它会打开审查代码生成准备情况页面,您可以查看和修复问题。在这个例子中,因为应用程序没有检测到问题,它打开定义输入类型页面。有关更多信息,请参见代码生成准备工具

    请注意

    代码分析器和代码生成准备工具可能无法检测到所有的代码生成问题。在消除了这两种工具检测到的错误或警告之后,使用MATLAB编码器以确定您的MATLAB代码是否有其他遵从性问题。

C/ c++代码生成支持的某些MATLAB内置函数和工具箱函数、类和System对象具有特定的代码生成限制。金宝app这些限制和相关的使用说明列在扩展功能对应参考页的部分。有关更多信息,请参见C/ c++代码生成支持的函数和对象金宝app

定义输入类型

由于C使用静态类型,代码生成器必须在代码生成时确定MATLAB文件中所有变量的类、大小和复杂性,也称为编译时.因此,必须指定所有入口点函数输入的属性。要指定输入属性,可以:

  • 通过提供一个脚本,使用示例输入调用入口点函数,指示应用程序自动确定输入属性。

  • 直接指定属性。

在本例中,定义输入的属性xcb,指定测试文件test.m代码生成器可以使用它自动定义类型:

  1. 输入或选择测试文件test.m

  2. 点击Autodefine输入类型

    测试文件,test.m,调用入口点函数,欧几里得,使用期望的输入类型。应用程序决定输入x双(3 x1)和输入cb双(3 x216)

  3. 点击下一个去…检查运行时问题的一步。

检查运行时问题

检查运行时问题步骤从入口点函数生成MEX文件,运行MEX函数,并报告问题。MEX函数生成的代码可以从MATLAB内部调用。执行此步骤是最佳实践,因为您可以检测和修复生成的C代码中较难诊断的运行时错误。默认情况下,MEX函数包括内存完整性检查。这些检查执行数组边界和维度检查。该检查检测为MATLAB函数生成的代码中内存完整性的违反。有关更多信息,请参见控制运行时检查

为了将MATLAB代码转换为高效的C/ c++源代码,代码生成器引入了优化,在某些情况下,会导致生成的代码的行为与原始源代码不同。看到生成代码与MATLAB代码的区别

  1. 打开检查运行时问题对话框中,单击检查问题箭头

  2. 检查运行时问题对话框中,指定一个测试文件或输入代码,使用示例输入调用入口点函数。对于本例,使用测试文件测试用来定义输入类型的。

  3. 点击检查问题

    该应用程序生成一个MEX函数。它运行测试脚本测试更换要求欧几里得调用生成的MEX。如果应用程序在MEX函数生成或执行期间检测到问题,它会提供警告和错误消息。单击这些消息导航到有问题的代码并修复问题。在这个例子中,应用程序不会检测到问题。

  4. 默认情况下,应用程序收集行执行计数。这些计数帮助您了解测试文件有多好test.m锻炼的欧几里得函数。查看行执行次数,单击查看MATLAB行执行计数.应用程序编辑器会在代码的左边显示一个彩色代码条。若要在代码上扩展颜色高亮显示并查看行执行数,请将光标放在条形图上。

    特定的绿色阴影表示此代码的行执行计数落在某个范围内。在这种情况下-loop执行215次。有关如何解释行执行计数和关闭计数集合的信息,请参见收集和查看行执行计数的MATLAB代码

  5. 点击下一个去…生成代码的一步。

请注意

在从MATLAB代码生成独立的C/ c++代码之前,生成一个MEX函数。运行生成的MEX函数,并确保它具有与MATLAB函数相同的运行时行为。如果生成的MEX函数生成的答案与MATLAB不同,或者生成错误,则必须在继续独立代码生成之前修复这些问题。否则,您生成的独立代码可能不可靠,并且具有未定义的行为。

生成C代码

  1. 打开生成对话框中,单击生成箭头

  2. 生成对话框中,设置构建类型静态库(lib)语言其他项目构建配置设置使用默认值。

    您可以选择生成MEX函数或其他C/ c++构建类型,而不是生成C静态库。对于MEX和C/ c++构建类型,可以使用不同的项目设置。当您在MEX和C/ c++代码生成之间切换时,请验证您所选择的设置。

  3. 点击生成

    MATLAB编码器生成一个独立的C静态库欧几里得工作\ codegen \ lib \欧几里得工作是包含教程文件的文件夹。的MATLAB编码器App表示代码生成成功。它在页面的左侧显示MATLAB源文件和生成的输出文件。在变量选项卡时,显示有关MATLAB源变量的信息。在目标建立日志选项卡,它显示构建日志,包括C/ c++编译器警告和错误。默认情况下,在代码窗口中,应用程序显示C源代码文件,euclidean.c.中查看不同的文件源代码输出文件窗格中,单击文件名。

  4. 点击查看报告在“报表查看器”中查看报表。如果代码生成器在代码生成期间检测到错误或警告,则报告将描述问题并提供问题MATLAB代码的链接。有关更多信息,请参见代码生成报告

  5. 点击下一个打开完成工作流程页面。

检查完成工作流页面

完成工作流程页表示代码生成成功。它提供了一个项目摘要和到生成的输出的链接。

比较生成的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双x [3]对应于输入x在MATLAB代码中。的大小x3.,它对应于您从MATLAB代码生成代码时使用的示例输入的总大小(3 x 1)。

    const双cb [648]对应于输入cb在MATLAB代码中。的大小cb648,它对应于从MATLAB代码生成代码时使用的示例输入的总大小(3 x 216)。在本例中,生成的代码使用一维数组来表示MATLAB代码中的二维数组。

    生成的代码有四个额外的输入参数:数组y_miny_maxidx,距离.这些数组用于返回输出值。它们对应于输出参数y_miny_maxidx,距离在原始的MATLAB代码。

  • 代码生成器保留函数名和注释。如果可能,代码生成器会保留变量名。

    请注意

    如果您的MATLAB代码中的变量被设置为常量值,那么在生成的C代码中它不会以变量的形式出现。相反,生成的C代码包含变量的实际值。

使用嵌入式编码器®,可以交互式地跟踪MATLAB代码与生成的C/ c++代码之间的关系。看到交互式跟踪MATLAB代码和生成的C/ c++代码(嵌入式编码)

为可变大小的输入生成C代码

生成的C函数euclidean.m只能接受与代码生成期间指定的示例输入大小相同的输入。然而,对应MATLAB函数的输入数组可以是任意大小的。在本教程的这一部分中,您将从下面生成C代码euclidean.m它接受可变大小的输入。

假设你想要xcb在生成的C代码中有这些属性:

  • 两者的第一个维度xcb大小可以变化到3.

  • 第二个维度x是固定的,有值吗1

  • 第二个维度cb大小可以变化到216

要指定这些输入属性:

  1. 定义输入类型步骤,输入测试文件test.m并点击Autodefine输入类型像以前一样。测试文件调用入口点函数,euclidean.m,使用期望的输入类型。应用程序决定输入x双(3 x1)和输入cb双(3 x216).这些类型指定固定大小的输入。

  2. 单击输入类型规范并编辑它们。属性可以指定变量大小,最大可达指定的限制前缀。例如,:3表示相应维度的大小可以变化到3..将类型更改为双(:3 * 1)x双(3 x: 216)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_datacb_datay_min_data,y_max_data对应于输入参数xcb输出参数y_miny_max在原始MATLAB函数中。C函数现在接受四个额外的输入参数x_sizecb_sizey_min_size,y_max_size的大小x_datacb_datay_min_data,y_max_data在运行时。

下一个步骤

目标 更多的信息

了解对MATLAB内置函数和工具箱函数、类和System金宝app对象的代码生成支持

C/ c++代码生成支持的函数和对象金宝app

生成c++代码

c++代码生成

生成和修改一个示例C主函数,并使用它来构建一个C可执行程序

在应用程序中使用示例C Main

将生成的文件打包成压缩文件

其他开发环境的包代码

优化生成代码的执行速度或内存使用

优化策略

将您的定制C/ c++代码集成到生成的代码中

从MATLAB代码调用C/ c++代码

了解代码生成报告

代码生成报告

交互式跟踪MATLAB代码和生成的C/ c++代码(嵌入式编码)