Qt C++ Matlab 混合编程测试使用文档 | 您所在的位置:网站首页 › matlab画动图运行速度太慢 › Qt C++ Matlab 混合编程测试使用文档 |
环境版本开发步骤
Matlab 动态链接库的生成Qt 调用环境配置C++ 对 Matlab 函数调用其他官方文档及常见问题
mwArray 类官方文档常见问题
作者个人博客: 作者博客,更多分享 内容首发: Qt C++ Matlab 混合编程测试使用文档 环境版本 Qt:5.9.0 MSVC 2017 64bit 编译器 Matlab:R2019b (64bit) Windows 11 64位 开发步骤本文就介绍使用 Qt 5.9 和 Matlab 进行混合编程的基本流程,主要包括: 如何在Matlab中将m文件编译为C++语言的DLL文件 如何在Qt项目中加入自定义DLL相关的LIB文件,以及MATLAB相关的LIB文件和H文件搜索路径 如何在Qt中调用自定义DLL中的函数,如何通过mwArray类传递输入输出参数 Matlab 动态链接库的生成 Matlab 函数的编写在 Matlab 中编写函数,这里编者以两个矩阵相加函数 matAdd 作为测试函数。并保存为 matAdd.m 文件。 function C= matAdd(A,B)% C= matAdd(A,B), 两个矩阵相加C=A+B;end注意:需要多个 Matlab 函数时,需要将各个文件保存到不同的Matlab文件中,在下面的步骤中统一集合成相关动态链接库和头文件。 设置MATLABCompiler 编译器在 Matlab 命令行输入下面的内容。 >> mbuild -setup C++MBUILD 配置为使用 'Microsoft Visual C++ 2017' 以进行 C++ 语言编译。注意:编者采用 'Microsoft Visual C++ 2017' 进行 C++ 编译,和 Qt 编译器保持一致,暂不清楚不同编译器是否会对结果造成影响。电脑上安装了Visual Studio 2017,MATLAB会自己查找可用的编译器。 Library Compiler在 Matlab 命令行输入下面的内容: >> deploytool并选择 ‘Library Compiler’ :“ApplicationCompiler”用于将m文件编译为exe文件直接运行,“Library Compiler”用于将m文件编译为DLL、COM组件等形式。我们要生成DLL文件,所以选择“Library Compiler”。 ‘TYPE’ 部分选择 C++ Shared Library ,“EXPORTED FUNCTIONS” 选择待添加的文件(这里可以添加多个函数文件)。右侧是MATLAB运行时库的安装打包方式,在本机上测试可选择“Runtime downloaded from web”。添加完毕后点击‘Package’ 进行编译和打包。 image-20220313203953140 Qt 调用环境配置打包完毕后,项目文件 matAdd.prj 目录下生成与其项目同名的子目录,即 \matAdd,该目录下有 3 个文件夹。我们主要需要 matAdd\for_redistribution_files_only 目录下是编译生成的.dll 、.lib和.h文件。其中.lib和.h文件是在Qt项目编译时需要用到的,.dll文件是程序运行时需要用到的。 image-20220313204821142这三个文件,需要复制到 Qt 的 pro 目录下。 image-20220313204929658 matAdd.lib 文件的加入 image-20220313205154849打开 pro 库,右键选择添加库,选择添加外部库,加入目录中的 matAdd.lib 文件,其他选择如图所示: 在 pro 文件中,将会出现下面几段代码: win32: LIBS += -L$$PWD/./ -lmatAdd INCLUDEPATH += $$PWD/.DEPENDPATH += $$PWD/.win32:!win32-g++: PRE_TARGETDEPS += $$PWD/./matAdd.libelse:win32-g++: PRE_TARGETDEPS += $$PWD/./libmatAdd.a为了方便查看matAdd.h的内容,还可以将matAdd.h文件添加到项目中,但是要注意不要修改matAdd.h文件的内容。 Matlab 依赖库和头文件搜索路径的加入。除了自己编译生成的DLL相关的.lib文件和头文件,要编译此Qt项目,还需要用到MATLAB的几个.lib文件和.h文件。 我的电脑上,MATLAB2019b安装在 D:/Program/matlab2019 目录下,在 testAdd.pro 文件中需要加入如下的设置: INCLUDEPATH += 'D:/Program/matlab2019/matlab/extern/include'INCLUDEPATH += 'D:/Program/matlab2019/matlab/extern/include/win64'win32: LIBS += -L'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft/' -llibmexwin32: LIBS += -L'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft/' -llibmxwin32: LIBS += -L'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft/' -llibmatwin32: LIBS += -L'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft/' -llibengwin32: LIBS += -L'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft/' -lmclmcrwin32: LIBS += -L'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft/' -lmclmcrrtINCLUDEPATH += 'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft'DEPENDPATH += 'D:/Program/matlab2019/matlab/extern/lib/win64/microsoft'INCLUDEPATH += 'D:/Program/matlab2019/matlab/extern/lib/win64'DEPENDPATH += 'D:/Program/matlab2019/matlab/extern/lib/win64'注意:注意,若路径名称中含有空格,需要使用quote(),如 #INCLUDEPATH+=$$quote(D:/MATLAB2017b/extern/include) 系统环境变量的配置若是程序发布到没有安装MATLAB的电脑上,需要用Matlab Compiler编译生成的安装包,本例就是 matAdd\for_redistribution目录下的MyAppInstaller_web.exe。 若只是要独立安装MATLAB运行时库,在MATLAB 命令行里输入 mcrinstaller可以得到离线的MATLAB运行时库安装文件的路径。 >> mcrinstaller更多相关内容见:在没有安装MATLAB的电脑上运行MATLAB程序 C++ 对 Matlab 函数调用测试设计 UI 界面如下所示: image-20220313210921486所用到的控件如下图所示: matAdd.dll 的初始化在使用 matAdd.dll 函数之前,需要调用 matAdd.h 里的函数 matAddInitialize 进行初始化 我们将初始化在窗口的构造函数里完成。下面是构造函数的代码: MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); // 不执行matAddInitialize()会报错,注意matAdd为文件名 if(matAddInitialize()) { ui->TextEdit->setText("matlab程序DLL初始化成功."); } else { ui->TextEdit->setText("*** matlab程序DLL初始化失败"); return; }} mwArray 类的使用(1)构造函数如下所示: mwArray(num_rows,num_cols,mxID,cmplx=mxREAL)num_rows表示行数, mwSize是整数类型 num_cols表示列数 mxID是mxClassID类型,表示元素的基本数据类型,常见的有如下的一些取值mxLOGICAL_CLASS mxCHAR_CLASS mxDOUBLE_CLASS mxSINGLE_CLASS mxINT8_CLASS mxUINT8_CLASS mxINT16_CLASS mxUINT16_CLASS mxINT32_CLASS mxUINT32_CLASS mxINT64_CLASS mxUINT64_CLASS cmplx是mxComplexity类型,有mxREAL和mxCOMPLEX两种取值,标书数组元素是实数或复数,缺省为mxREAL (2)mwArray数组的赋值 mwArray:: SetData(mxUint64* buffer, mwSizelen)其中,buffer必须是一维数组,即便mwArray变量是一个二维数组,len是一维数组的元素个数,等于行数乘以列数。在给二维数组赋值时,buffer必须按列存储数据(见代码内容)。 void MainWindow::on_pushButton_clicked(){// 两个矩阵相加, C=A+B//读取矩阵A int rowCntA=ui->spinBoxA_Row->value(); int colCntA=ui->spinBoxA_Col->value(); int elementCntA=rowCntA*colCntA; //元素个数 //一维数组,用于C++向 MATLAB数组传递数据 double *arrayA=new double[elementCntA]; int N=0; //C++的一维数组的元素索引号 for(int i=0;itableA->columnCount();i++) //逐列读取,序列化存储到一维数组 for (int j=0; jtableA->rowCount();j++) { arrayA[N]=ui->tableA->item(j,i)->text().toDouble(); N++; } //定义数组,行,列,double类型 mwArray matrixA(rowCntA,colCntA,mxDOUBLE_CLASS, mxREAL); //将C++ 的一维数组arrayA存储到 MATLAB的二维数组matrixA matrixA.SetData(arrayA,elementCntA);(3)mwArray数组元素的读取 可以使用mwArray::Get()函数读取数组的元素, 例如,对于二维数组,采用Get()函数读取数据的代码一般是 int dim=2; // 二维数组double value=matrixA.Get(dim,j,i); //按照dim维数数组读出,第j行, 第i列也可以不用行号、列号,而用序号读取,如 int dim=2; // 二维数组double value=matrixA.Get(dim,N); //按照dim维数数组读出,第N个元素这里的N是按列排列的元素的总的序号。对于二维数组,还是按照行号、列号更直观一些。 也可以直接使用mwArray的“()”操作符读取数组元素,如 double value=matrixC(j,i); //直接用数组下标索引,第j行,第i列 double value=matrixC(N); //直接按元素序号读取, 第N个元素 Matlab 函数的调用在我们已经通过上述方式进行 mwArray 进行 数组的定义与赋值后,我们可以直接通过 Matlab 函数文件的原函数名进行函数的调用,需要传入的参数为: nargout:输出变量个数 matrixC: 保存返回矩阵的 mwArray类,需要指定相关属性。 matrixA、matrixB:matlab 原函数中的两个参数矩阵。 //计算, C=A+B int rowCntC=rowCntA; int colCntC=colCntA; //定义数组,行,列,double类型 mwArray matrixC(rowCntC,colCntC,mxDOUBLE_CLASS, mxREAL); int nargout=1;//输出变量个数 // 调用函数,计算 C = A + B matAdd(nargout,matrixC,matrixA,matrixB); 其他官方文档及常见问题 mwArray 类官方文档Class used to pass input/output arguments to C++ functions generated by MATLAB Compiler SDK 常见问题错误使用 mbuild (line 166) Unable to complete successfully. 未找到支持的编译器。 Qt与Matlab混合编程细节总结 学习笔记:Qt与Matlab混合编程及遇到的诸多问题(附DEMO) 以上链接内容仅供参考,实际操作过程会遇到无数的坑。。。下面的网址可以解决百分之八九十的问题: stackoverflow CSDN |
CopyRight 2018-2019 实验室设备网 版权所有 |