Qt C++ Matlab 混合编程测试使用文档
Qt C++ Matlab 混合编程测试使用文档
[TOC]
环境版本
- 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 文件。
1 | function C= matAdd(A,B) |
注意:需要多个 Matlab 函数时,需要将各个文件保存到不同的Matlab文件中,在下面的步骤中统一集合成相关动态链接库和头文件。
设置MATLABCompiler 编译器
在 Matlab 命令行输入下面的内容。
1 | >> mbuild -setup C++ |
注意:编者采用 ‘Microsoft Visual C++ 2017’ 进行 C++ 编译,和 Qt 编译器保持一致,暂不清楚不同编译器是否会对结果造成影响。电脑上安装了Visual Studio 2017,MATLAB会自己查找可用的编译器。
Library Compiler
在 Matlab 命令行输入下面的内容:
1 | >> 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’ 进行编译和打包。
Qt 调用环境配置
打包完毕后,项目文件 matAdd.prj 目录下生成与其项目同名的子目录,即 \matAdd,该目录下有 3 个文件夹。我们主要需要 matAdd\for_redistribution_files_only 目录下是编译生成的.dll 、.lib和.h文件。其中.lib和.h文件是在Qt项目编译时需要用到的,.dll文件是程序运行时需要用到的。
这三个文件,需要复制到 Qt 的 pro 目录下。
matAdd.lib 文件的加入
打开 pro 库,右键选择添加库,选择添加外部库,加入目录中的 matAdd.lib 文件,其他选择如图所示:

在 pro 文件中,将会出现下面几段代码:
1 | win32: LIBS += -L$$PWD/./ -lmatAdd |
为了方便查看matAdd.h的内容,还可以将matAdd.h文件添加到项目中,但是要注意不要修改matAdd.h文件的内容。
Matlab 依赖库和头文件搜索路径的加入。
除了自己编译生成的DLL相关的.lib文件和头文件,要编译此Qt项目,还需要用到MATLAB的几个.lib文件和.h文件。
我的电脑上,MATLAB2019b安装在 D:/Program/matlab2019 目录下,在 testAdd.pro 文件中需要加入如下的设置:
1 | INCLUDEPATH += 'D:/Program/matlab2019/matlab/extern/include' |
注意:注意,若路径名称中含有空格,需要使用quote(),如
#INCLUDEPATH+=$$quote(D:/MATLAB2017b/extern/include)
系统环境变量的配置
若是程序发布到没有安装MATLAB的电脑上,需要用Matlab Compiler编译生成的安装包,本例就是 matAdd\for_redistribution目录下的MyAppInstaller_web.exe。
若只是要独立安装MATLAB运行时库,在MATLAB 命令行里输入 mcrinstaller可以得到离线的MATLAB运行时库安装文件的路径。
1 | mcrinstaller |
更多相关内容见:在没有安装MATLAB的电脑上运行MATLAB程序
C++ 对 Matlab 函数调用
测试设计 UI 界面如下所示:
所用到的控件如下图所示:

matAdd.dll 的初始化
在使用 matAdd.dll 函数之前,需要调用 matAdd.h 里的函数 matAddInitialize
进行初始化
我们将初始化在窗口的构造函数里完成。下面是构造函数的代码:
1 | MainWindow::MainWindow(QWidget *parent) : |
mwArray 类的使用
(1)构造函数如下所示:
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数组的赋值
1 | mwArray:: SetData(mxUint64* buffer, mwSizelen) |
其中,buffer必须是一维数组,即便mwArray变量是一个二维数组,len是一维数组的元素个数,等于行数乘以列数。在给二维数组赋值时,buffer必须按列存储数据(见代码内容)。
1 | void MainWindow::on_pushButton_clicked() |
(3)mwArray数组元素的读取
可以使用mwArray::Get()函数读取数组的元素,
例如,对于二维数组,采用Get()函数读取数据的代码一般是
1 | int dim=2; // 二维数组 |
也可以不用行号、列号,而用序号读取,如
1 | int dim=2; // 二维数组 |
这里的N是按列排列的元素的总的序号。对于二维数组,还是按照行号、列号更直观一些。
也可以直接使用mwArray的“()”操作符读取数组元素,如
1 | double value=matrixC(j,i); //直接用数组下标索引,第j行,第i列 |
Matlab 函数的调用
在我们已经通过上述方式进行 mwArray 进行 数组的定义与赋值后,我们可以直接通过 Matlab 函数文件的原函数名进行函数的调用,需要传入的参数为:
- nargout:输出变量个数
- matrixC: 保存返回矩阵的 mwArray类,需要指定相关属性。
- matrixA、matrixB:matlab 原函数中的两个参数矩阵。
1 | //计算, C=A+B |
其他官方文档及常见问题
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混合编程及遇到的诸多问题(附DEMO)
以上链接内容仅供参考,实际操作过程会遇到无数的坑。。。下面的网址可以解决百分之八九十的问题: