基于Qt平台框架实现C/C++调用Matlab动态库

记录一下。希望对同样有该问题的有用。查了挺多文档,参考了大佬。

本文旨在通过Qt调用Matlab生成的动态共享库(DLL),若是别的调用请查看其余大佬文章。

一、MATLAB 生成 DLL文件

1.1 编译环境配置

ps:(问题注意点写前面)   QT调用matlab需要编译器位数一致!!!!!!!不然会出现函数未定义等错误。

Qt 在 Windows 平台的编译环境一般有两种,分别为 MinGW 和 MSVC,为使 DLL 文件的编译平台与 Qt 保持一直,在配置时需要选择相同的编译器,且位数必须一致,比如我使用的环境均为MSVC2017 64bit。MSVC 可以通过安装 Visual Studio 进行配置,网上相关资料很多,这里就不说了。MinGW 没用过,但可以在 MATLAB 附加功能中安装,打开附加功能管理器后,直接搜索Mingw即可。

在 MATLAB 命令行窗口,使用mbuild –setup命令查看 MATLAB 中可以配置的编译环境。

如果没有可选编译器,需要自行配置后进行下一步操作。

输入命令后,会显示当前可配置的编译器,如下图所示。

这里我选择C++语言,完成配置。

(需要注意的是,matlab每次重启后,都要重新按以上步骤进行mbuild -setup)

1.2 打包生成 DLL 文件

先使用 MATLAB 编写一个两个数相加的函数,文件名为 add_matlab.m,具体代码如下:

function c = add_matlab(a,b)
c = a + b;
end

在 MATLAB 命令行窗口输入 deploytool命令,弹出如下对话框。(也可以在上方app里直接找Library Compiler 编译器)

选择 Library Compiler 编译器,如下图所示。

TYPE选择C++ Shared LibraryEXPORTED FUNCTIONS选择要编译的文件,这里选择前面编写好的add_matlab.m文件,如下所示。

选择完成后,点击 Package 按钮,选择编译后的文件放置位置,开始编译打包,稍等片刻即可完成,输出目录中有如下三个文件夹。

                        ​​​​​​​        

for_testing 目录下的文件,用于测试。

for_redistribution目录中程序MyAppInstaller_web.exe用于安装 MATLAB 运行时库和本项目生成的 DLL 、LIB 和 H 文件,将程序部署至没有 MATLAB 环境中电脑时,可以使用此方法。

for_redistribution_files_only目录中的 DLL 、LIB 和 H 文件,就是在 Qt 项目中要使用的文件。H 和 LIB 文件用于 Qt 程序调用,DLL 文件用于保障程序运行。有文章说 v2 目录中的 .ctf 文件在较低版本的 MATLAB 中影响 DLL 接口中的初始化函数,较高版本的MATLAB不需要。在无法初始化时,可以将该文件与 DLL 文件一同放入 debug 文件夹下尝试解决。

二、Qt  调用 DLL

2.1 创建好Qt项目,添加外部库(DLL)

创建一个 Qt 项目,在项目文件目录下新建一个名为matlab_libs(文件夹名可以自定义随便取),将 MATLAB 编译生成的for_redistribution_files_only目录下的文件全部拷贝至该文件夹下。

右键点击 Qt 项目目录名,选择添加库外部库

库文件选择Matlab_libs中的add_matlab.lib,点击下一步完成 Qt 外部库的添加。

完成后会在项目 .pro 文件中添加如下信息:

win32: LIBS += -L$$PWD/matlab_libs/ -ladd_matlab

INCLUDEPATH += $$PWD/matlab_libs
DEPENDPATH += $$PWD/matlab_libs

2.2 添加 MATLAB 其他依赖库和头文件路径

Qt 项目编译时,不仅需要自己添加的 MATLAB 编译后的库文件,还需要其他 MATLAB 依赖库文件,在工程 .pro 文件中添加如下内容:

# MATLAB 用到的.lib库文件及其搜索路径
LIBS += -LD:/MATLAB/MATLAB_Runtime/v95/extern/lib/win64/microsoft/ -llibmx
LIBS += -LD:/MATLAB/MATLAB_Runtime/v95/extern/lib/win64/microsoft/ -llibmat
LIBS += -LD:/MATLAB/MATLAB_Runtime/v95/extern/lib/win64/microsoft/ -llibeng
LIBS += -LD:/MATLAB/MATLAB_Runtime/v95/extern/lib/win64/microsoft/ -lmclmcr
LIBS += -LD:/MATLAB/MATLAB_Runtime/v95/extern/lib/win64/microsoft/ -lmclmcrrt
LIBS += -LD:/MATLAB/MATLAB_Runtime/v95/extern/lib/win64/microsoft/ -llibmex

# .h文件搜索路径
INCLUDEPATH += D:/MATLAB/MATLAB_Runtime/v95/extern/include
INCLUDEPATH += D:/MATLAB/MATLAB_Runtime/v95/extern/include/win64
(根据自己MATLAB安装位置来修改)

上述路径根据自己安装位置进行替换,需要注意的是,文件路径中不得有空格,若有空格可以使用 quote(),如下:

INCLUDEPATH += $$quote(D:/MATLAB/MATLAB_Runtime/v95/extern/include)

2.3 环境配置

如果要发布程序或者运行在没有 MATLAB 环境的电脑需要安装 MATLAB 运行库,可以通过for_redistribution目录中MyAppInstaller_web.exe程序进行安装,也可以直接下载运行库安装程序,下载的运行库必须和生成 DLL 文件的 MATLAB 软件是同一个版本,MATLAB 运行库链接:https://ww2.mathworks.cn/products/compiler/matlab-runtime.html,
运行库的安装根据提示一直点击确定即可。

2.4 调用add_matlab DLL库函数

(1)初始化库函数

在调用 add_matlab() 函数前,必须先使用 add_matlabInitialize() 函数初始化库函数。

(初始化函数在add_matlab.h头文件有,根据不同库,可能有点区别)

(2)MATLAB 编译生成的 DLL 函数接口,保存在add_matlab.h文件中,add_matlab() 函数如下:

extern LIB_add_matlab_CPP_API void MW_CALL_CONV add_matlab(int nargout, mwArray& c, const mwArray& a, const mwArray& b);

nargout 为函数输出参数的个数,表示其后面紧跟着 nargout 个输出参数。

其他参数为 MATLAB 程序中自定义的输入输出参数,数据类型均为mwArray类。

(3)mwArray

mwArray类是用于将输入/输出参数传递给 MATLAB Compiler SDK 生成的 C++ 函数的类。

具体使用可参考:mwArray类说明-CSDN博客

2.5 编译运行

简单示例代码具体如下:

#include "matlabtest.h"
#include "ui_matlabtest.h"

#include "matlab_libs/add_matlab.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

     if (!add_matlabInitialize())
     {
         qDebug("add_matlab unsuccessfully initialized");
         return;
     }
     ccc();

}

Widget::~Widget()
{
    delete ui;
}

void Widget::ccc()
{
    double a = 6.3;
    double b = 9.2;
    mwArray mwA(1,1,mxDOUBLE_CLASS);
    mwArray mwB(1,1,mxDOUBLE_CLASS);
    mwArray mwC(1,1,mxDOUBLE_CLASS);
    //设置数据
    mwA.SetData(&a,1);
    mwB.SetData(&b,1);
    qDebug()<<mwA.Real().ToString();
    qDebug()<<mwB.Real().ToString();
    //计算
    add_matlab(1,mwC,mwA,mwB);
    qDebug()<<mwC.Real().ToString();

}

三:问题

可参考:

QT与matlab混编及完整错误详解-CSDN博客

QT和matlab混合编程以及maltab程序化初始化失败_matlab qt_+++.的博客-CSDN博客

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt调用MATLAB引擎有多种方式。一种常见的方式是将MATLAB函数封装成.dll文件,然后在Qt平台调用.dll文件实现。另一种方式是将MATLAB函数导出成.exe可执行程序,再在Qt平台调用.exe可执行程序。还有一种方式是直接在Qt平台调用MATLAB Engine引擎,但这需要计算机上安装有MATLAB软件。\[1\] 在进行Qt调用MATLAB引擎的过程中,可能会出现执行交慢的情况。为了提高执行速度,建议不要关闭已经打开的MATLAB Command Window,下次启动时会更快一些。具体的数据传递和接收方法可以参考MATLAB官方文档。\[2\] 要在Qt平台实现C/C++调用MATLAB函数的全流程,需要进行环境配置,并将MATLAB代码转换成C/C++代码和相关动态链接库。具体的步骤包括:基本调用方式介绍、环境配置、将MATLAB程序写成函数形式、配置MATLAB的C编译器,将.m文件转换成动态链接库、在Qt中添加MATLAB的依赖库和头文件搜索路径、在Qt中添加外部库、在Qt工程的头文件中添加生成的MATLAB库的头文件、在Qt中编写使用DLL内函数的代码等。如果在实施过程中遇到问题,可以参考相关文档进行解决。\[3\] #### 引用[.reference_title] - *1* *3* [超详细基于Qt平台实现C/C++调用Matlab函数全流程](https://blog.csdn.net/m15279530607_163/article/details/129471386)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Qt 调用MATLAB引擎混合编程](https://blog.csdn.net/u010058695/article/details/121682716)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值