一、MATLAB Coder介绍

MATLAB Coder可从 MATLAB 代码生成适用于各种硬件平台(从桌面计算机系统到嵌入式硬件)的 C 和 C++ 代码。它支持大多数 MATLAB 语言和广泛的工具箱。您可以将生成的代码作为源代码、静态库或动态库集成到您的工程中。生成的代码是可读且可移植的。您可以将它与现有 C 和 C++ 代码及库的关键部分结合使用。您还可以将生成的代码打包为 MEX 函数,用于在MATLAB环境中进行验证或加速。

二、配置C/C++编译器

配置C/C++编译器一般有两种方案:
第一种是下载Visual Studio,下载完成后基本就不需要配置了,比较省事,Visual Studio下载及安装地址可以参考:安装Visual Studio2017
第二种是下载C语言编译器MinGW-w64,下载及安装地址可以参考:MinGW-w64的安装及配置教程

由于我之前用Visuai Studio做过项目,因此我选择的是第一种方案,配置完成后,在MATLAB命令行窗口输入以下命令可判断是否配置完成:

mex -setup
mex -setup c++

当不出现报错时,就证明配置完成,如下图所示。
在这里插入图片描述

三、MATLAB Coder介绍

3.1 进入MATLAB Coder界面

打开MATLAB Coder的方法有两种:
第一种方法是在菜单栏APP中找到MATLAB Coder,如下图所示:
在这里插入图片描述
第二种方法是直接在MATLAB命令行窗口中输入coder:
在这里插入图片描述
打开后,MATLAB Coder初始界面如下图所示:
在这里插入图片描述

3.2 MATLAB Coder步骤介绍

观察上方,一共有六个步骤,分别是:

  • Select Source File
  • Review Code Generation
  • Define Input Types
  • Check for Run-Time Issues
  • Generate Code
  • Finish Workflow

在这里插入图片描述

四、案例1——将m文件转变为C/C++代码

MATLABCoder可以从 MATLAB代码生成独立的、可读性强、可移植的 C/C++代码。
使用MATLAB Coder产生代码的3个步骤:
①准备用于产生代码的MATLAB算法;
②检查MATLAB代码的兼容性(有些matlab代码语句并不能生成c/c++代码);
③产生最终使用的源代码或MEX。

4.1 准备用于产生代码的MATLAB算法

创建一个子函数mul,函数内容为:

function c = mul(a, b)

c = a * b;

该函数的主要功能就是执行两个数值相乘的操作。
然后创建一个主函数,在主函数中调用该子函数,主函数程序如下:

x=2;
y=3;
mul(x,y)

4.2 检查MATLAB代码的兼容性

在命令窗口,输入mex-setup,选中一个存在的编译器;
然后打开MATLAB Coder,
第一步——选择源文件
选择需要转换成C/C++的文件名:这里选择mul.m,选择完成后,点击右下角的Next进入第二步
在这里插入图片描述
第二步——定义输入类型
为每个入口点函数定义输入类型,这里如果有主函数,直接选择主函数即可,MATLAB会自动推导出该函数的输入类型:
选择主函数后,点击右侧的“Autodefine Input Types”,MATLAB会自动进行推导,推导后如下图所示:
在这里插入图片描述
如果没有问题,点击右下角的Next进入第三步。

第三步——检查运行问题
点击右侧的“Check for Issues”,MATLAB会检查是否存在故障,如果不存在则结果如下图所示:
在这里插入图片描述
点击右下角的Next进入第四步。

第四步——生成代码
选择C或者C++语言,点击右侧“Generate”可以生成代码,
在这里插入图片描述
最终生成的C代码如下,点击View Report可以查看生成报告:
在这里插入图片描述
如果一切正常,点击右下角的Next进入第五步。

第五步——完成代码
点击Next后,源文件生成成功,此时输出可以从Generated output中查看。
在这里插入图片描述

4.3 产生最终使用的源代码或MEX

打开上述文件夹,可以查看最终生成的C源文件。
在这里插入图片描述
然后打开C/C++编译器,建立一个控制台应用程序,将生成的相关文件mul.h、mul.c、rtwtypes.h、mul_types.h、tmwtypes.h拷到相关目录下并添加到应用程序中;

【注意】:需要注意的是,需要将上面提到的.h文件放置到头文件文件夹中,选中“头文件”右键——>“添加”——>“现有项”:
在这里插入图片描述
然后将mul.c文件放置在源文件文件夹中,最后在资源文件文件夹中新建一个main.c文件,整体文件目录如下:
在这里插入图片描述
在main.c中写入调用程序,示例如下:

#include<stdio.h>
#include"mul.h"
int main(){
	int x = 2, y = 3, z;
	z = mul(x, y);
	printf("z=%d\n", z);
}

运行可以发现,程序运行成功,输出z=6。

ok!案例1介绍完毕~

五、案例2——将m文件转变为C/C++代码

案例2同样是如上三步。

5.1 准备用于产生代码的MATLAB算法

首先自己新建一个文件夹,然后将教程文件从文件夹 matlabroot\help\toolbox\coder\examples\euclidean 复制到本地工作文件夹。此处,matlabroot 是 MATLAB 安装文件夹,例如 C:\Program Files\MATLAB\R2019a。要将这些文件复制到您的当前文件夹,首先需要打开MATLAB,然后进入该文件夹下,最后再命令行窗口中输入如下命令:

copyfile(fullfile(matlabroot,'help','toolbox','coder','examples','euclidean'))

这里稍微解释一下这一行代码,fullfile函数根据文件各部分信息合成完整的路径名,copyfile函数复制源文件或源文件夹到当前目录下。

运行完成后,文件夹中会出现如下文件:
在这里插入图片描述
本案例中使用的文件为: euclidean_data.mat、euclidean.m 和 test.m。
euclidean_data.mat包含两段数据:三维欧几里德空间中的一个点以及三维欧几里德空间中的一组其他点。更具体地说:

  • x 是一个 3×1 列向量,表示三维欧几里德空间中的一个点;
  • cb 是一个 3×216 数组。cb 中的每列都表示三维欧几里德空间中的一个点;

euclidean.m包含euclidean 函数,该函数在本示例中实现核心算法。该函数接受 x 和 cb 作为输入。它计算 x 和 cb 中每个点之间的欧几里德距离,并返回以下量:

  • 列向量 y_min,它等于 cb 中表示与 x 距离最近的点的列;
  • 列向量 y_max,它等于 cb 中表示与 x 距离最远的点的列;
  • 二维向量 idx,它包含 cb 中向量 y_min 和 y_max 的列索引;
  • 二维向量 distance,它包含计算出的到 x 的最小和最大距离;

test.m 将数据文件 euclidean_data.mat 加载到工作区中。接着,它调用函数 euclidean 来计算 y_min、y_max、idx 和 distance。然后,脚本在命令行中显示计算出的量。

加载 euclidean_data.mat 是在调用核心算法之前执行的预处理步骤。显示结果是后处理步骤。
在 MATLAB 中运行测试脚本 test.m。输出显示 y、idx 和 distance。
在这里插入图片描述

5.2 检查MATLAB代码的兼容性

  1. 在 MATLAB 编辑器中打开 euclidean.m。MATLAB 编辑器右上角的代码分析器消息指示标记为绿色。分析器未在代码中检测到错误、警告或改进机会。
    在这里插入图片描述
  2. 在函数声明后面添加 %#codegen 指令:
function [y,idx,distance] = euclidean(x,cb) %#codegen

%#codegen 指令提示代码分析器识别特定于代码生成的警告和错误。
代码分析器消息指示标记变为红色,表示它检测到代码生成问题。
在这里插入图片描述

  1. 要查看警告消息,将光标移到带下划线的代码片段上。

警告指示,代码生成要求先对变量 idx 和 distance 进行完全定义,然后才可以对它们进行下标索引。出现这些警告是因为代码生成器必须在这些变量在代码中首次出现时确定其大小。要解决此问题,需要ones 函数同时分配和初始化这些数组,修改为:

idx = ones(1,2);
distance = ones(1,2)*norm(x-cb(:,1));

修改完成后,代码分析器消息指示标记再次变为绿色,表示它没有再检测到任何代码生成问题。
保存文件。

5.3 产生最终使用的源代码或MEX

打开MATLAB Coder,
【为简单起见,这里就不放图了,如果想看图,可以查看案例1】
第一步——选择源文件
选择需要转换成C/C++的文件名:这里选择euclidean.m,选择完成后,点击右下角的Next进入第二步
第二步——定义输入类型
为每个入口点函数定义输入类型,这里如果有主函数,直接选择主函数即可,MATLAB会自动推导出该函数的输入类型:
选择“test.m”后,点击右侧的“Autodefine Input Types”,MATLAB会自动进行推导,如果没有问题,点击右下角的Next进入第三步
第三步——检查运行问题
点击右侧的“Check for Issues”,MATLAB会检查是否存在故障,如果不存在,则点击右下角的Next进入第四步
第四步——生成代码
选择C或者C++语言,点击右侧“Generate”可以生成代码,最终生成的C代码,点击右下角的Next进入第五步
第五步——完成代码
点击Next后,源文件生成成功,此时输出可以从Generated output中查看。
在这里插入图片描述

可以查看生成的 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] 对应于 MATLAB 代码中的输入 x。x 的大小为 3,对应于从 MATLAB 代码生成代码时使用的示例输入的总大小 (3×1)。const double cb[648] 对应于MATLAB 代码中的输入 cb。cb 的大小为 648,对应于从 MATLAB 代码生成代码时使用的示例输入的总大小 (3×216)。在本例中,生成的代码使用一维数组来表示 MATLAB 代码中的二维数组。

生成的代码有四个额外的输入参数:数组 y_min、y_max、idx 和 distance。这些数组用于返回输出值。它们对应于原始 MATLAB 代码中的输出参数 y_min、y_max、idx 和 distance。

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

如果对你有所帮助,记得点个赞哟~♥

参考链接:
【1】MATLAB Coder Documentation
【2】使用 MATLAB Coder App 生成 C 代码 - MATLAB & Simulink

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐