Qt与matlab混合编程

本文详细介绍了如何在Qt项目中利用Matlab,包括将.m文件编译为动态库并在Qt中调用,直接启动Matlab引擎进行数据交互,以及通过中间文件txt实现Qt和Matlab的数据交换。讲解了Qt工程配置、动态库编译、引擎启动、数据转换等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


以下内容使用的操作系统、软件及编译器版本:win10、Qt5.9.6(msvc2015_64)、matlab R2018b

.m文件示例

matAdd.m

function [C]= matAdd(A, B)
% 两个矩阵数相加
C = A + B;
end

Qt工程中引用matlab相关的库和文件

.pro文件作如下设置,其中 D:/MATLAB/R2018b 为matlab的安装路径,可以根据自身实际安装的路径进行更改

# .h文件
INCLUDEPATH += D:/MATLAB/R2018b/extern/include
INCLUDEPATH += D:/MATLAB/R2018b/extern/include/Win64

# MATLAB 的.lib库文件
INCLUDEPATH += D:/MATLAB/R2018b/extern/lib/win64/microsoft
DEPENDPATH += D:/MATLAB/R2018b/extern/lib/win64/microsoft

win32: LIBS += -LD:/MATLAB/R2018b/extern/lib/win64/microsoft/-llibmex
win32: LIBS += -LD:/MATLAB/R2018b/extern/lib/win64/microsoft/-llibmx
win32: LIBS += -LD:/MATLAB/R2018b/extern/lib/win64/microsoft/-llibmat
win32: LIBS += -LD:/MATLAB/R2018b/extern/lib/win64/microsoft/-llibeng
win32: LIBS += -LD:/MATLAB/R2018b/extern/lib/win64/microsoft/-lmclmcr
win32: LIBS += -LD:/MATLAB/R2018b/extern/lib/win64/microsoft/-lmclmcrrt

Qt中调用matlab的几种方法

1.动态库方法

将.m文件编译成C++可以直接调用的动态库,之后在Qt程序中直接使用。这种方法最为简单,也最为常见。

maltlab函数编译动态库
  1. matlab中打开需要编译的.m文件,命令行中输入
mbuild -setup

在这里插入图片描述
输入命令后回车,根据弹出的选项进行对应的选择

在这里插入图片描述
之后在命令行中输入

deploytool

在弹出的窗口中选择 Library Compiler

在这里插入图片描述

之后在弹出的窗口中选择要编译的动态库的类型,点击 + 添加.m文件(可一次添加多个),设置生成的动态库的名称,保存当前工程(若此时不保存,在点击生成之前系统会提示保存),最后点击 Package 生成动态库。

在这里插入图片描述
在这里插入图片描述

生成成功后,在matlab工程下将看到生成的动态库

在这里插入图片描述

Qt中调用matlab生成的动态库

Qt工程中.pro引用生成的动态库和对应头文件

LIBS += F:/Programs/QT/MatlabTest/link/matAdd.lib
INCLUDEPATH += F:/Programs/QT/MatlabTest/link/

Qt程序中调用动态库中的函数

if (!matAddInitialize()) // DLL初始化
{
    qDebug() << "DLL initialization failed";
    return;
}

double vectA[]={1,2,3};  // 向量A
double vectB[]={5,6,7};  // 向量B

int rowCnt=1;   // 行数
int colCnt=3;   // 列数
int elementCnt=3;  // 元素个数

mwArray matrixA(rowCnt, colCnt, mxDOUBLE_CLASS, mxREAL);  // 定义数组
matrixA.SetData(vectA, elementCnt);  // 将C++ 的一维数组存储到MATLAB的二维数组

mwArray matrixB(rowCnt, colCnt, mxDOUBLE_CLASS, mxREAL);
matrixB.SetData(vectB, elementCnt);

// 计算
mwArray matrixC(rowCnt, colCnt, mxDOUBLE_CLASS, mxREAL);  // 定义数组,double类型
int nargout=1;  // 输出变量个数
matAdd(nargout, matrixC, matrixA, matrixB);  // 调用函数计算,返回的结果保存在matrixC变量中

// 读取结果
int dim = 1;  // 按照向量读出matrixC
double av = matrixC.Get(dim, 1);  // 第1个元素
double bv = matrixC.Get(dim, 2);  // 第2个元素
double cv = matrixC.Get(dim, 3);  // 第3个元素

//    int dim = 2; //按照二维数组读出matrixC
//    double av = matrixC.Get(dim, 1, 1); //第1行,第1列
//    double bv = matrixC.Get(dim, 1, 2); // 第1行,第2列
//    double cv = matrixC.Get(dim, 1, 3); // 第1行,第3列

小结

在Qt中使用matlab编译生成的动态库是最为简单和常见的方法,但是在一些情形下matlab无法将程序编译成动态库(脚本程序或某些函数不支持编译等),这种情况下则必须采用其它办法在C++中调用matlab程序。

2. Qt调用matlab引擎

在Qt中可以直接启动matlab引擎,此后可从Qt程序中向matlab发送指令进行相关操作,指令的语法和matlab命令窗口语法一致。

Qt启动matlab引擎

头文件需要包含

#include "engine.h"

启动matlab引擎

Engine *ep = nullptr;
if(!(ep = engOpen(nullptr)))  // 启动matlab引擎
{
    qDebug() << "无法启动matlab引擎";
    return;
}
engSetVisible(ep, false);  // 隐藏matlab自带命令窗口

其中,当matlab引擎启动的时候,默认是会弹出matlab的命令行窗口的,此时若不需要,可以使用 engSetVisible(ep, false) 函数将该窗口隐藏。

在这里插入图片描述

Qt和matlab之间数据交互

仍以matAdd函数为例,在Qt中定义A和B两个变量,调用matAdd.m文件计算得到结果C,将其返回Qt程序并显示。

// 给变量赋值
double init1 = 3.0;
mxArray *a = nullptr;
a = mxCreateDoubleMatrix(1, 1, mxREAL);
memcpy((void*) mxGetPr(a), (void*)&init1, sizeof (double));
engPutVariable(ep, "A", a);
mxDestroyArray(a);

double init2 = 1.0;
mxArray *b = nullptr;
b = mxCreateDoubleMatrix(1, 1, mxREAL);
memcpy((void*) mxGetPr(b), (void*)&init2, sizeof (double));
engPutVariable(ep, "B", b);
mxDestroyArray(b);

engEvalString(ep, "cd F:/Programs/others/MatlabTest");  // 向matlab发送字符串命令

engEvalString(ep, "one=matAdd(A,B);");
mxArray *result = engGetVariable(ep, "one");   //将MATLAB结果传回qt

qDebug() << *mxGetPr(result);  // 打印结果

engEvalString 函数用于从Qt向matlab发送命令,engGetVariable 函数用于获取matlab计算得到的结果,返回值是 mxArray* 类型,mxGetPr 用于将matlab支持的mxArray类型转换为C++支持的数据类型(double*)。

关闭matlab引擎
engClose(ep);  // 关闭matlab引擎
其他
matlab函数中有多个返回值时Qt指令写法

.m文件

function [C, D]= matAdd(A, B)
% 两矩阵相加和相减
C = A + B;
D = A - B;
end

Qt程序写法如下,指令的语法和在matlab命令行中写法一致。

engEvalString(ep, "[one, two]=matAdd(A,B);");
mxArray *result = engGetVariable(ep, "one");   //将MATLAB结果传回qt
mxArray *result1 = engGetVariable(ep, "two");
直接调用.m文件

当.m文件中是脚本程序时,可以直接执行.m文件

engEvalString(ep, "load('XXX/XXX/XXX/xxx.m');");
mxArray类型与C++数组互转

上面的示例中传入matlab的变量只是两个double型的数(也可以理解为1行1列的矩阵),当传入或者返回的数据是多行多列的矩阵时,写法与上文略有不同。

二维数组转mxArray*
   double init3[2][5] = {{1, 2, 3, 4, 5},{11, 22, 33, 44, 55}};
   mxArray *c = nullptr;
   c = mxCreateDoubleMatrix(2, 5, mxREAL);
   memcpy((void*) mxGetPr(c), (void*)init3, sizeof (init3));
mxArray*转二维数组
int M = mxGetM(c);  // 行数
int N = mxGetN(c);  // 列数
double *ans = mxGetPr(c);  // 转为数组类型

// 打印数组结果
for(int i = 0; i < M; ++i)
{
    for(int j = 0; j < N; ++j)
    {
        cout << *(ans + (i * N + j)) << " ";
        cout.flush();
    }
    cout << "\n";
}
小结

使用Qt调用matlab引擎方法比较比较灵活,相当于在Qt中打开了一个matlab,但是matlab引擎启动较慢,并且需要进行二者之间的数据交互,容易出错,此外还需要一定的matlab语法基础。

3.使用txt等中间文件在Qt和matlab之间进行数据交互

这种方法比较简单,Qt和matlab两者基本互相独立,将Qt获取到的数据保存到txt等中间文件当中,matlab程序中需要的参数从txt文件中读取,并将返回结果同样保存为txt文件,供Qt程序读取和显示。
(若在运行Qt程序过程中,全程不想打开matlab软件,则可以使用Qt启动带命令窗口的matlab引擎,之后的操作在命令行窗口中进行。)

简单粗暴最有效。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值