步骤1: 使用matlab生成dll文件,
并将dll文件放入QT相应工程目录文件夹中的debug文件夹中,
右击QT工程名,添加外部库
matlab2021a,QT5.9.9。所用c++部件2017
#include "mainwindow.h"(工程固有)中添加dll伴生的h头文件
步骤2:修改pro文件(仅添加如下内容)
TARGET = Matlab #工程名
TEMPLATE = app
# Matlab 运行库的头文件
INCLUDEPATH += $$quote(D:/Program Files/Polyspace/R2021a/extern/include)
#目录名称中有空格时才用 $$quote
INCLUDEPATH += $$quote(D:/Program Files/Polyspace/R2021a/extern/include/win64)
win32: LIBS+=-L$$quote(D:/Program Files/Polyspace/R2021a/extern/lib/win64/microsoft) -llibmex
win32: LIBS+=-L$$quote(D:/Program Files/Polyspace/R2021a/extern/lib/win64/microsoft) -llibmx
win32: LIBS+=-L$$quote(D:/Program Files/Polyspace/R2021a/extern/lib/win64/microsoft) -llibmat
win32: LIBS+=-L$$quote(D:/Program Files/Polyspace/R2021a/extern/lib/win64/microsoft) -llibeng
win32: LIBS+=-L$$quote(D:/Program Files/Polyspace/R2021a/extern/lib/win64/microsoft) -lmclmcr
win32: LIBS+=-L$$quote(D:/Program Files/Polyspace/R2021a/extern/lib/win64/microsoft) -lmclmcrrt
#以上路径均为matlab安装文件路径
步骤3:matlab程序调用
QT中调用的m程序没有返回值,调用格式一般在h头文件的最后
例如
extern LIB_initpop_CPP_API void MW_CALL_CONV initpop(int nargout, mwArray& p, const mwArray& x);
参数1是输出参数个数,此处为1,因此紧跟后面即参数2就是函数的调用结果的接收数组,再后面是输入参数。
void MainWindow::on_pushButton_clicked()
{
if (!initpopInitialize()) //DLL 初始化
{
return; //自行增加
}
mwArray num(1,1,mxDOUBLE_CLASS);
num = ui->lineEdit->text().toDouble();
mwArray p(1,1,mxDOUBLE_CLASS);
QByteArray vec;
mwArray a(1,10,mxDOUBLE_CLASS);
initpop(1,a,num);
}
m文件:输入参数1个,返回行矩阵
问题1:matlab函数返回值问题
1.1 返回值为常数
本例中,修改initpop函数的函数头为 function y= initpop();%其中y为常数
extern LIB_initpop_CPP_API void MW_CALL_CONV initpop(int nargout, mwArray& y);
但是mwArray是matlab与C++混编中的数据格式,在QT中输出需要格式转换
若m程序中有一个int返回值,没有输入参数
mwArray a(1,1,mxDOUBLE_CLASS, mxREAL);//定义数组
int x;
initpop(1,a);
x=(int)a;
qDebug()<<x;
若m程序中有返回值,有输入参数
initpop(1,a,num); a为返回值,num为输入参数
若m程序中没有返回值,没有输入参数
TSP();
若m程序中没有返回值,有输入参数 %matlab中无int的数据类型且只满足C语言赋值方法,不满足C++赋值关
TSP(a); %系,需要是int8
1.2 返回值为数组
1.
QStringList str = {"abc", "qwe", "upo"};
foreach(QString s , str )
{
qDebug()<<s<<" ";
}
2
mwArray input1(5,2,mxINT8_CLASS);
mwArray input2(5,2,mxINT8_CLASS);
mwArray input1(5,2,mxINT8_CLASS);
mwArray input2(5,50,mxINT8_CLASS);
mwArray input3(5,2,mxINT8_CLASS);
mwArray input4(5,2,mxINT8_CLASS);
mwArray FC(1,25,mxCELL_CLASS);
mwArray a(1,1,mxDOUBLE_CLASS);
mwArray b(1,1,mxDOUBLE_CLASS);//mwArray为调用MATLAB时,参数类型为mwArray
mwArray mac_num(1,1,mxDOUBLE_CLASS);
mwArray cost(1,1,mxDOUBLE_CLASS);
tuple<mwArray,mwArray, mwArray, mwArray> StudIntro=make_tuple(input1,input2,input3,input4); //元胞数组
FC(1)=input1;
mac_num=ui->lineEdit->text().toDouble();
cost=ui->lineEdit_2->text().toDouble();
Untitled2(4,a,b,input1,input2,mac_num,cost);
qDebug()<<(int)a;
qDebug()<<(int)b;
//我这里的input为返回值,
//mwArray类型矩阵赋值语句是input1.SetData(output1, 4);SetData是output1往input1赋值,即输入
int output1[10];
int output2[250];
input1.GetData(output1,10); //10代表着矩阵中元素总数,5*2=10
input2.GetData(output2,250); //GetData是input2往output2里赋值,即输出
for (int i=0;i<10;i++) {
qDebug()<<output1[i]<<endl;
}
for (int i=0;i<250;i++) {
qDebug()<<output2[i]<<endl;
}
1.3 QT接收matlab函数返回值问题
//输出
mwArray mac_num(26,1,mxDOUBLE_CLASS);
mwArray Current_rate(1,1,mxDOUBLE_CLASS);
current(2,mac_num,Current_rate,material_num1,material_num2,material_num3,material_num4,material_num5,p,t);
double value = Current_rate.Get(1,1,1); //三个一的意思分别是一维,第1行,第1列
qDebug()<<value;
ui->result_cur->setText(QString::number(value));
问题2:程序异常结束(仅仅是dll库出现问题,与其他无关)
解决办法之一:程序出现问题,若是删除debug文件夹,一定要将dll文件保存,重新构建后再次放入debug文件夹中,不然就会程序异常结束
2.未将dll文件放入debug文件夹
3.多个dll文件,不用时没有彻底删除
具体做法:删掉build-Login-Desktop_Qt_5_9_9_MSVC2017_64bit-Debug整个文件夹,然后点击构建,执行qmake,按照你自己的dll使用顺序将dll库文件逐个加入到debug文件夹中,每加一个运行一下,总有成功的一次,原因就在于你把你没用的dll库也加入其中,导致错误。
具体原因是我在调用这三个dll库时,竟然大意的将调用槽函数写成一样,所以就有没有使用dll库而在debug文件夹中加入了dll库文件的离奇错误泪流满面,大意一下浪费一天。
connect(newActi1 ,SIGNAL(triggered()),this,SLOT(cal_step()));
connect(newActi2 ,SIGNAL(triggered()),this,SLOT(cal_step()));
connect(newActi3 ,SIGNAL(triggered()),this,SLOT(cal_step()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::cal_step()
{
Current_ *c1 =new Current_();
this->hide();
c1->show();
}
void MainWindow::cal2_step()
{
Max_productivity *max1 =new Max_productivity();
this->hide();
max1->show();
}
void MainWindow::cal3_step()
{
Min_Cost *min1 =new Min_Cost();
this->hide();
min1->show();
}
问题3:定义QlineEdit数组,数据的输出
问题4:创建QLineEdit数组,通过QInputDialog输入数据,并显示到QLineEdit,然后应用数据
问题5:Qt:无法解析的外部命令
1.包含dll运行指令的cpp文件被重置,但依旧在一个工程中,删除debug文件
2.信号对应的槽函数更改后,需要删除整个build文件夹
3.新加入了信号与槽函数
4.未添加外部库,即dll文件
5.工程中的全局变量,static静态成员可以实现(单cpp文件),实例如下:
h文件
namespace Ui {
class Dialog_0;
}
class Dialog_0 : public QDialog
{
Q_OBJECT
public:
explicit Dialog_0(QWidget *parent = nullptr);
~Dialog_0();
public:
static QString Process_quantity; //静态成员变量的定义
static QString cost_bugdet;
private:
Ui::Dialog_0 *ui;
};
cpp文件
#include "dialog_0.h"
#include "ui_dialog_0.h"
QString Dialog_0::Process_quantity=0; //静态成员函数一定要初始化,且初始化程序
//需要放在任意函数外部
QString Dialog_0::cost_bugdet=0;
Dialog_0::Dialog_0(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog_0)
{
ui->setupUi(this);
}
Dialog_0::~Dialog_0()
{
delete ui;
}
void Dialog_0::on_next_procedure_clicked()
{
QMessageBox::information(this,"attention","即将输入每道工序详细信息");
Process_quantity=ui->Edit_macNum->text();
cost_bugdet=ui->Edit_cost->text();
qDebug()<<Process_quantity<<" "<<cost_bugdet;
//Mac_num = Process_quantity;
//Cost = cost_bugdet;
Dialog_1 *dia1 =new Dialog_1();
this->close();
dia1->show();
}
5.工程中的全局变量,static静态成员可以实现(多cpp文件),实例如下:
传入数据的h文件定义static变量
public:
static QString start_text; //静态成员变量的定义
static QString end_text;
传入数据的cpp文件函数外初始化static变量,函数中传入数据。
QString MapChannel::start_text= " "; //静态成员变量的定义
QString MapChannel::end_text= " ";
void MapChannel::recvStringSlot(const QString &text){
qDebug()<<text;
start_text = text;
}
其他cpp文件需要数据的只需包含头文件就可直接使用了
MapChannel::start_text //类名::数据
问题6:matlab的多个m文件生成dll文件
1.使用deploytool时只选择主程序的m文件进行生成dll文件,然后在qt调用主程序的function名字,我的例程中,原本主程序是没有function,但是deploytool生成dll出错,做出一些如下修改,
Matlab中的m文件
function TSP()
....(内容)
end
QT文件
if (!TSPInitialize()) //DLL 初始化
{
return; //自行增加
}
TSP();
qt启动后,TSP中调用的其他m文件,后台会自动调用,完美解决困惑...
2.F:\QtCreator\test\zhuchengxu.h:16: error: C1083: 无法打开包括文件: “mclmcrrt.h”: No such file or directory
Build > Run qmake
问题7:dll生成时,报错:在matlab路径中不能找到该文件(凭记忆翻译的)
在执行deploytool时尽量使MATLAB处于以下路径,即matlab刚启动时的初始路径
MATLAB的工程文件路径中有中文路径,
预设--工程-修改路径
预设--工程-日志记录
问题8:QT出现MATLAB is exiting because of fatal error
1.MATLAB的源程序的书写错误,在matlab中无法编译运行,因此也在QT中无法运行
2.QT调用时未传入输入参数
3.QT在使用mwArray定义输入或输出参数后,直接用具体数值定义,未考虑mwArray数据类型与int/string类型之间的转换,就会报这个错,例如:
错误一:
mwArray material_num(1,1,mxINT8_CLASS);
material_num=1000;
错误二:
mwArray material_num(1,1,mxINT8_CLASS); Int8不等于Int,使用double就好了
material_num=a.toInt();
问题9:mwArray的应用
int in1[10]={7,27,15,19,20,15,23,13,0,0};
mwArray input1(5,2,mxINT8_CLASS);
input1.SetData(in1,10); //in1传入input1
问题10:输入参数是元胞数组时
int in1[10]={7,27,15,19,20,15,23,13,0,0};
int in2[10]={4,25,8,22,0, 0,0, 0,0,0};
int in3[10]={7,40,8,37,9,25,0, 0,0,0};
int in4[10]={8,16,9,15,10,9,12,6,0,0};
mwArray input1(5,2,mxINT8_CLASS);
mwArray input2(5,2,mxINT8_CLASS);
mwArray input3(5,2,mxINT8_CLASS);
mwArray input4(5,2,mxINT8_CLASS);
input1.SetData(in1,10);
input2.SetData(in2,10);
input3.SetData(in3,10);
input4.SetData(in4,10);
mwArray FC(1,25,mxCELL_CLASS);
FC(1)=input1;
FC(2)=input2;
FC(3)=input3;
FC(4)=input4;
问题11:QT界面中文显示乱码
1.QString::fromLocal8Bit("对");
2.将乱码所在cpp文件用记事本打开,另存为utf_8格式,替换原有cpp文件
3.pro文件中添加
QMAKE_CXXFLAGS += -execution-charset:utf-8
如果还出错,删除debug文件夹,重新构建。
问题12:QTreeWidgetItem的触发信号问题
问题13:error: C1083: 无法打开包括文件: “mclmcrrt.h”: No such file or directory
看D:/Program Files/Polyspace/R2021a/extern/include(matlab安装路径中)这个文件夹中是否有该h文件,有的话,刷新一下pro文件的matlab路径设置(删掉在复制一下),或者把最后的/删掉。
问题12:exe打包时matlab程序调用失败
已经将matlab的dll库文件放在exe所在路径,并修改cpp文件中的文件路径,依旧失败。。。
QString qstrFileName = QDir::currentPath();
QString text = QString("/%1.txt").arg(vary_name);
qstrFileName.append(text);
QString fileName = qstrFileName;
-L$$PWD/ - - - 表示 .pro所在目录
mclmcrrt9_10.dll不能放在exe所在文件路径下
将microsoft文件夹复制到exe所在文件夹,而删掉的INCLUDEPATH的头文件,需要根据错误提示一一添加。
最终的pro文件里matlab调用库全部代码如下,
win32: LIBS+=-L$$PWD/microsoft -llibmex
win32: LIBS+=-L$$PWD/microsoft -llibmx
win32: LIBS+=-L$$PWD/microsoft -llibmat
win32: LIBS+=-L$$PWD/microsoft -llibeng
win32: LIBS+=-L$$PWD/microsoft -lmclmcr
win32: LIBS+=-L$$PWD/microsoft -lmclmcrrt
更多推荐
QT与matlab混编及完整错误详解
发布评论