软件环境:
windows 10
MATLAB 2016a
Visual Studio 2019
设置MATLAB中的C++编译器:
在MATLAB中输入:
mex -setup
选择MSVC编译器,如果找不到编译器可以输入一下命令查找支持的编译器版本:
mex -setup -v
或进入MATLAB目录中的binwin64mexopts中查看支持的编译器xml文件,找不到当前系统的编译器可以进入MATLAB官网下载对应的编译器的xml文件,如VS2019的编译器文件下载地址:
https://www.mathworks.com/matlabcentral/answers/uploaded_files/220928/MATLAB%20VS2019%20Support.zip
将下图两个文件复制到binwin64mexopts中,并打开注册表,在注册表内找到
计算机HKEY_LOCAL_MACHINESOFTWAREWOW6432NodeMicrosoftVisualStudioSxSVS7,
没有就在相应目录下创建对应项,在该目录下创建“16.0”的字符串,将“ Visual Studio”安装目录的地址赋值给它,如下图:
之后重新在MATLAB中输入“mex -setup”应该就能找到对应的编译器。
MATLAB生成EXE文件
在MATLAB输入命令
deploytool
选择第一项即是编译生成EXE文件
选择需要编译的m文件,当需用执行EXE的电脑中已经有了MATLAB的运行环境可以选红色框的选项,否则建议选择下面一项,会将编译出EXE所需要的运行环境一起打包起来,供使用者安装。
编译好了生成三个文件夹:
- for_redistribution包含用于安装应用程序和MATLAB Runtime的文件;
- for_testing文件夹包含创建的所有由MCC创建的文件,像二进制文件和jar,头和源文件,使用这些文件来测试安装;
- for_redistribution_files_only文件夹包含应用程序的重新发布所需的文件。这些文件可以分发到那些有MATLAB或者有 MATLAB Runtime 的用户的电脑上;
- PackagingLog.txt是由编译器生成的日志文件;
进入for_redistribution_files_only目录双击 exe 文件查看结果:
MATLAB生成C++库
在MATLAB中创建一个简单的函数,功能两个矩阵相加:
function out = addMatFunc(input_1,input_2 )
out = input_1 + input_2;
disp(out)
end
输入“deploytool”选择第三项
选择需要编译的m文件,选择编译为C++库:
若生成失败:
报错内容: fatal error LINK1181: 无法打开输入文件“libMatlabDataArray.lib”;则需要进入 MATLABbinwin64mexopts 目录中修改编译器xml文件,以msvcpp2019.xml为例:
将第49行、78行与79行分别替换为下面的内容:
49:LINKLIBS="/LIBPATH:"$MATLABROOTexternlib$ARCHmicrosoft" libmx.lib libmex.lib libmat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
78:LINKFLAGS="/nologo /manifest"
79:LINKLIBS="/MACHINE:AMD64 /LIBPATH:"$MATLABROOTexternlib$ARCHmicrosoft" mclmcrrt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
重新编译m文件。
编译成功后在for_redistribution_files_only中可以看到生成了对应的头文件、静态库文件与动态库文件。
最后,配置C++工程,在C++中调用生成的库。 将生成的.dll、.lib、.h文件复制到C++工程目录下:
注意:如果使用的MATLAB是64位的版本,那么C++的程序也要在x64下配置。如果使用的MATLAB是32位的版本,那么C++的程序也要在win32下配置。
VS中配置头文件路径与链接库路径:
编写C++代码,mwArray为MATLAB所支持的数据格式,其可以通过指针来赋值,注意:MATLAB是读取连续内存按列存储到矩阵,因此需要注意数据的转换!!
// funcTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include"addMatFunc.h"
using namespace std;
#pragma comment(lib, "./addMatFunc.lib" )
#define WIDTH 20
#define HEIGHT 20
int main()
{
double* input_1 = new double[WIDTH * HEIGHT];
double* input_2 = new double[WIDTH * HEIGHT];
double* output = new double[WIDTH * HEIGHT];
// 初始化矩阵:input_1 input_2均为20*20的矩阵
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
input_1[i * HEIGHT + j] = i;
input_2[i * HEIGHT + j] = 1;
}
}
//初始化MATLAB
addMatFuncInitialize();
// 声明与MATLAB支持的mwArray变量
mwArray input_array_1(HEIGHT, WIDTH, mxDOUBLE_CLASS, mxREAL);
mwArray input_array_2(HEIGHT, WIDTH, mxDOUBLE_CLASS, mxREAL);
mwArray output_array(HEIGHT, WIDTH, mxDOUBLE_CLASS, mxREAL);
// 赋值
input_array_1.SetData(input_1, HEIGHT * WIDTH);
input_array_2.SetData(input_2, HEIGHT * WIDTH);
// 函数的输出变量数目
int nargout = 1;
// 执行MATLAB编译的库函数
addMatFunc(nargout, output_array, input_array_1, input_array_2);
// 获取输出,写入output的指针中
output_array.GetData(output, HEIGHT * WIDTH);
// 结束
addMatFuncTerminate();
return 0;
}
编译并运行工程可以得到结果:
用VS查看 output 指针指向的内存:与打印的结果一致,成功实现在C++中调用MATLAB生成的库函数。
MATLAB代码与C++工程文件网盘链接,提取码2ywc
https://pan.baidu.com/s/1LLVabX0NpjaTJ81DeD0Dmgpan.baidu.com一些重要提示:
注意编译器的版本与MATLAB的版本,不同版本的编译器会链接不同MATLAB静态库(MATLAB 2017后升级很多静态库),可以通过MATLABbinwin64mexopts中xml文件来查看,根据个人环境配置灵活修改。
如果使用的MATLAB是64位的版本,那么C++的程序也要在x64下配置。
如果使用的MATLAB是32位的版本,那么C++的程序也要在win32下配置。
MATLAB是读取连续内存按列存储到矩阵,因此需要注意数据的转换。