一:问题描述
参考:C++调用Matlab生成的DLL动态链接库进行混合编程(win10+VS2015+Matlab2016b)_青青韶华的博客-CSDN博客_c++调用matlab生成的dll
最近经手的项目需要调用MATLAB算法运算,并获取返回的结果,需要先在VS2017中实现调用函数,再将这个函数打包成DLL供QT调用,相当于动态链接库DLL中还套了一个DLL,实现步骤及主义事项如下:
二:MATLAB打包DLL
MATLAB命令行输入mbuild -setup,选择VS2017编译器进行C语言编程,编译器应该是需要和安装的VS版本一致,我没有具体测试。
MATLAB命令行输入mex -setup,选择VS2017编译器进行C语言编程。
命令行输入mcc -W cpplib:DuQuZuiXinFile -T link:lib TDduquzuixinwenjian.m -C
其中:
-W是控制编译之后的封装格式;
cpplib是指编译成C++的lib,如果需要编译成C的lib,就用lib即可,去掉cpp;
cpplib后面的是需要生成文件的文件名,是自己取的,我们取名为DuQuZuiXinFile;
-T表示目标,link:lib表示要连接到一个库文件的目标,目标的名字即是.m函数的名字。
其他具体含义可以通过mcc –help命令查看,注意参数的大小写。
.m文件夹下就会生成对应的dll文件,其中.dll .h .lib .ctf四个文件是我们所需要的。
MATLAB环境变量设置:E:\MATLABR2021b\bin\win64 ——具体根据安装路径
三:VS2017调用 MATLAB打包的DLL,并再将函数打包成DLL
VS2017新建项目,选择动态链接库(如果只需要在VS2017中调用,不需要再打包的话,直接新建控制台项目即可)。
自己修改项目名称和路径。
在项目属性-C/C++-常规-附加包含目录中添加MATLAB头文件,具体路径根据MATLAB安装位置而定。
E:\MATLABR2021b\extern\include
在项目属性-链接器-常规-附加库目录中添加MATLAB为MVS编译器准备的库文件。
E:\MATLABR2021b\extern\lib\win64\microsoft
在VC++目录中的包含目录和库目录最好也添加一下。
在项目属性-链接器-输入-附加依赖项中添加mclmcrrt.lib,libmat.lib,libmx.lib,XXX.lib(你需要调用的dll)。
点击应用-确定,至此VS2017环境配置完成。
将MATLAB打包完成的四个文件添加到VS项目目录中(注意.ctf文件必须加,否则初始化会失败)。
在pch.cpp(创建DLL项目自动生成的)中写要实现的函数,要包含头文件有MATLAB打包的.h和系统自动生成的framework.h。使用MATLAB打包的函数之前记得先初始化。
if (!FFTInitialize())
{
cout << "FFTInitialize Failed\n";
return -1;
}
在pch.h中要添加函数声明,声明格式为:
extern"C" __declspec(dllexport) int ReadData(double* array1, double* yinpin, double* tezhengzhi, double* pinlv, double* status);
然后点击上方工具栏中生成-生成解决方案(如果创建的控制台项目,直接点击本地Windows调试器即可),即在项目目录下-x64-Debug目录下生成DLL文件。
至此,VS2017打包完成。
四:QT调用VS2017打包的DLL文件
QT调用时需要的文件有VS2017打包的TD.lib、TD.dll以及pch.h、framework.h。
新建一个QT项目,选择编译器为MVS2017,在项目目中新建include文件夹,将TD.lib、TD.dll、pch.h以及MATLAB打包的.dll .h .lib .ctf文件复制进去(用到的都要添加进去)。
QT界面右击项目-添加库-外部库,选择VS2017打包的TD.lib
添加完后.pro 文件中就会多出以下代码(也可以在pro文件中直接敲代码)
win32: LIBS += -L$$PWD/include/ -lTD
INCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/include
至此,QT环境配置完成。
在widget.cpp中写调用函数即可,注意包含头文件pch.h。
运行结果:
五:可能存在的问题
- 帧不在模块中
- 无法解析的外部符号WinMain
- 如果QT运行时,直接显示程序异常退出,检查是否所有.ctf文件都放入include文件中。
- 总是显示mwArray未定义或者函数未定义时,检查项目属性界面的编译条件与主界面是否一致。