目录
前言
刚毕业工作发现团队目前是采用Matlab与C/C++混合编程,代码主体为M文件,其中很多函数都需要利用C代码来进行实现,推进下一步IP设计的工作(这一部分我也不太懂,如RTL等等,只知道与Verilog、FPGA有关)。
公司电脑是Matlab 2020b or 2021b配合Visual Studio 2017使用,高版本Matlab与低版本Visual Studio安装完直接就能使用。
我自己电脑是学校期间装的 Matlab2020b ,由于想熟悉一下M、C/C++混合编译,因此想在自己电脑上配置一下环境。
VS我是直接在微软VisualStudio官网的最新版 Visual Studio 2022 Community 版本,想着新点用着也应该问题不大,结果发现在Matlab中使用 >>mex -setup 命令时无法配置为使用’Microsoft Visual C++ 2022 ©’ 以进行 C 语言编译,故着手从网上查找资料进行配置,但发现网上资料对于Matlab与Visual Studio 2022混合编程的资料基本没有,自己刚好误打误撞在不重装、升级Matlab版本到2022a、b的情况瞎解决了问题。下面以 Matlab2020b 配置 Visual Studio 2022 为例给出具体解决办法。
一、构造编译器的配置文件到Matlab安装目录
在Matlab中使用 MEX 可以编译C/C++ ,需要先配置好编译器,可以使用 >>mex -setup 命令来设置。如果电脑上是先安装的Visual Studio,然后安装Matlab,那么一般情况下,只需要在命令行输入 >>mex -setup 按照提示选择即可完成编译器的设置。
但是,假如是先安装的Matlab后安装的Visual Studio,或者其它一些原因,很可能 >>mex -setup 命令无法找到计算机中的Visual Studio编译器,因此需要进行一些修改才能成功配置编译器。
在Matlab的安装目录 …\MATLAB\R2020b\bin\win64\mexopts 目录中有各种编译器的配置文件,Matlab就是依靠这些xml文件和编译器建立关联,对应编译器的 .xml 文件会到windows系统的注册表中读取编译器和SDK的路径信息,之所以 >>mex -setup 命令无法找到编译器就是因为注册表中缺少编译器和SDK的路径信息。
这里是我的电脑 …\mexopts 下配置文件,原本是没有 红色矩形框 中 msvc2022.xml 和 msvcpp2022.xml 两个 .xml 文件的。根据网上方法,可以在高版本的Matlab中得到你所需要的配置文件,我没有这么做的原因一个是懒得重新安装Matlab,另外也不确定Matlab2022a、b中是否有没有上述两个配置文件,在网上也查不到相关信息。
因此,我就想着能不能自己构造这两个文件,根据2015、2017和2019版本的 .xml 文件,发现还是有规律的,而且配置文件基本没有变化,这里是msvc2019.xml 和 msvcpp2019.xml 文件的内容。
其实,只需要将两个文件进行修改就可以了:
- 将两个文件的第3行 Name=“Microsoft Visual C++ 2019 ©” 改为 Name=“Microsoft Visual C++ 2022 ©”;
- 将两个文件的第4行 ShortName=“MSVCPP160” 改为 ShortName=“MSVCPP170”;
- 将两个文件的第6行 Version=“16.0” 改为 Version=“17.0”;
- 最后将将两个文件中的所有 [16.0,17.0) 改为 [17.0,18.0),每个文件中均有12处需要修改。
不确定我有没有遗漏的修改的地方,如果嫌麻烦也可以直接下载 msvc2022.xml 和 msvcpp2022.xml 这两个文件: msvc2022.xml、msvcpp2022.xml ,提取码:6y42 。
二、在Matlab中配置为使用’Microsoft Visual C++ 2022 ©’ 以进行 C 语言编译
若在没有 msvc2022.xml 和 msvcpp2022.xml 在Matlab命令行输入 >>mex -setup ,则会出现 错误使用 mex :
为了清楚Matlab2020b搜索编译器和SDK的过程,可以使用 >>mex -setup -v 命令可以看到搜索过程:
在将构造的配置文件 msvc2022.xml 和 msvcpp2022.xml 加入到Matlab的安装目录 …\2020b\bin\win64\mexopts 目录中,在Matlab命令行中输入 >>mex -setup -v 搜索过程为:
可以看到,此时成功将Matlab的MEX 配置为使用 ‘Microsoft Visual C++ 2022 ©’ 以进行 C 语言编译。
在其他资料中有提到需要修改注册表或者增加系统环境变量等操作,但我操作完以上步骤后就已经配置成功了,我想的是可能系统自动帮我进行上述提到的一系列操作。
如果你的Matlab配置 Visual Studio失败,可以参考一下参考资料。
三、验证M文件与C文件混合编译
- 首先,新建一个工程文件夹,新建一个.m文件保存在此文件夹中。
clc
clear all
close all
a = 1;
b = 5;
c = MyAdd(a, b);
disp(' ');
disp([' MyC = ' num2str(c)]);
fprintf(['\n']);
fprintf([' MyC = ' num2str(c) '\n']);
在此.m文件中有一个 c = MyAdd(a, b) 函数,Matlab中没有这个函数,自己也没有定义,因此是无法直接运行的。
- 打开VS2022,新建一个.c或者.cpp文件,命名需要与.m文件中所调用的函数名相同,即 MyAdd.c 或 MyAdd.cpp均可。
/*=================================================================
* mexfunction.c
*
* This example demonstrates how to use mexFunction. It returns
* the number of elements for each input argument, providing the
* function is called with the same number of output arguments
* as input arguments.
* This is a MEX-file for MATLAB.
* Copyright 1984-2018 The MathWorks, Inc.
* All rights reserved.
*=================================================================*/
#include "mex.h"
void add(double* x, double* y, double* z)
{
*z = *x + *y;
}
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
int i;
double *A;
double *B;
double *C;
/* Examine input (right-hand-side) arguments. */
mexPrintf("\n%d input argument(s).", nrhs);
for (i = 0; i < nrhs; i++) {
mexPrintf("\n\tInput Arg %i is of type:\t%s ", i, mxGetClassName(prhs[i]));
}
A = mxGetPr(prhs[0]); //取得输入变量的指针
B = mxGetPr(prhs[1]);
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); //创建输出矩阵
C = mxGetPr(plhs[0]);
add(A, B, C);
//* C = (*A) + (*B) ;
/* Examine output (left-hand-side) arguments. */
mexPrintf("\n\n%d output argument(s).\n", nlhs);
if (nlhs > nrhs)
mexErrMsgIdAndTxt("MATLAB:mexfunction:inputOutputMismatch",
"Cannot specify more outputs than inputs.\n");
}
此例程是根据 mexFunction.c 修改的,可以在Matlab官方文档中搜索 mexFunction 得到,更多内容请参见官方文档:
doc mex
- 在Matlab命令行中输入 >>mex MyAdd.cpp 对其进行编译;
- 此时在Matlab中运行.m文件即可。
四、配置Cuda加速Matlab程序
在查找资料过程发现可以用 Cuda加速Matlab程序 (是我太菜了),同样也需要与Visual Studio版本对应的.xml配置文件,在Matlab的安装目录 …\MATLAB\R2020b\toolbox\parallel\gpu\extern\src\mex\win64 中,Matlab2020b中一共有三种版本的配置,分别是2015、2017和2019。
打开看了一下与 msvc2022.xml 和 msvcpp2022.xml 很像,我想着是不是可以用同样的方法编一个.xml就可以了,由于我的台式机为A家显卡,应该是没办法试了,之后用笔记本尝试一下。
具体配置步骤和方法请参考参考资料。
总结
自己误打误撞试成功了,还是挺幸运的。另外,走了一遍整个流程对编写mexFunction也是很有帮助的,之后还需要进一步学习,不然看着团队的代码就头大,原理,原理不懂,代码,代码变量多得头晕。
参考资料
[1] Matlab2016及以上版本设置VS编译器
[2] 解决matlab遇到的“错误使用 mex未找到支持的编译器或 SDK。”
[3] 快速解决matlab出现错误使用mex,未找到支持的编译器或 SDK的提示
[4] 低版本MATLAB配置高版本Visual Studio进行C/C++编译
[5] 在Matlab中通过mex使用cuda的方法