Qt(C++)与Matlab混合编程

来源:互联网 发布:tomcat数据库密码设置 编辑:程序博客网 时间:2024/06/06 02:33

前言:最近用到了Qt和Matlab混合编程的东西,其实本质上就是C++和Matlab混合编程。看了help文档,去看了资料,也看了Matlab的官方文档,有的关键地方也没有说明白。本人是小菜鸟一枚,在学习的过程中CSDN给了我很大帮助,我也希望将自己学到的东西回馈给CSDN的用户们。

简介

Matlat和C++混合编程有几个方式。
1. 通过Matlab调用C/C++,原理是通过mex生成dll,然后通过调用dll的方式来完成的。我没有用过,所以不展开。
2. 通过C/C++来调用MATLAB。这个又有两个方式,1.通过将m文件生成dll文件,再提供给VC来调用,这个完了一下就放弃了,貌似有坑。2.通过调用MATLAB的API来调用。本文档最主要的是来解释调用MATLAB的API来编程

如何查找API文档

在MATLAB的帮助文档中搜索关键字MATLAB Engine API,然后转到关键字Call MATLAB Function from C and C++ Appllication这个页面上会有一些示例代码。如
engdemo.c
engwidemo.c
engdemo.cpp

C and Fortran Engine Library Functions下面有这些接口函数。
这里写图片描述

代码示例

Matlab代码如下

function T = function(Tarr,n)%%%%%%%%%%%%%%%%%%%Tarr输入一个3*4的矩阵%n是一个double类型变量%T是返回一个double类型变量%%%%%%%%%%%%%%%%%%...%代码省略...

C++代码如下

     //********************************************     // C++这边欲传输给matlab的数     //*******************************************     double c_Tarr[12] = {1,2,3,4,5,6,7,8,9,10,11,12};     double c_n = 5;     //*******************************************     // 用一个空字符串去作为参数调用engOpen打开matlab进程     //******************************************     Engine *ep;     if (!(ep = engOpen(""))) {        fprintf(stderr, "\nCan't start MATLAB engine\n");        return EXIT_FAILURE;        }     //*******************************************     //将C++这边的数转换为mxArray类型的(所有的数据类型都要转换为mxArray矩阵)     //要特别注意数据的转换!!!     //数组转换:我们的c_Tarr是12个元素,那么构造成3*4的矩阵会按照先列后行的形式构造     //也就是说,先将元素添加给列。那么c_Tarr构造完成后会是这样一个矩阵:     //                        1 4 7 10       //                        2 5 8 11     //                        3 6 9 12     //单个元素转换,就先构造一个1*1的矩阵就行了(mxCreateDoubleMatrix(row,col,···))      //******************************************      mxArray *mxTarr = NULL,*mxN = NULL;      mxTarr = mxCreateDoubleMatrix(3,4,mxREAL);      mxN = mxCreateDoubleMatrix(1,1,mxREAL);       memcpy((char*)mxGetPr(mxTarr),(char*)c_Tarr,sizeof(c_Tarr));      memcpy((char*)mxGetPr(mxTarr),(char*)&c_n,sizeof(double));     //*******************************************     //往matlab上写东西,基本上就只要用两个接口函数     //engEvalString:往matlab上输入字符命令     //engPutVariable:将数组赋给符号     //function.m我放在了c:\matlab_function目录下面,所以cd进去了     //******************************************     engEvalString(ep,"clear all");     engEvalString(ep,"cd \'c:\\matlab_function'");     engPutVariable(ep,"Tarr",mxTarr);     engPutVariable(ep,"n",mxN);     engEvalString(ep,"T = function(Tarr,n)");     //******************************************     //获得返回值T     //engGetVariable:从matlab的工作区间获得变量值     //******************************************     mxArray * p_mxT = mxCreateDoubleMatrxi(1,1,mxREAL);     p_mxT = engGetVariable(ep,"T");     double *pT = mxGetPr(p_mxT);     std::cout<<"T的值是"<<pT[0];     //******************************************     //释放mxArray指针占用的内存与关闭matlab     //******************************************     mxDestroyArray(mxTarr);     mxDestroyArray(mxN);           mxDstroyArray(p_mxT);     engEvalString(ep,"close");     engClose(ep);

Qt混合编程设置

如果你用VS2013的话,一定要将平台设置为matlab一样的,比如matlab是64位,你一定要设置为x64平台。设置好后,要将matlab的库文件包含进工程,这样的方法网上很多。这里重点将一下Qt怎么设置。
Qt下点.pro文件

INCLUDEPATH += ./matlab_include\./matlab_include/win64LIBS += ./matlab_lib/libeng.lib\./matlab_lib/libmat.lib\./matlab_lib/libmex.lib\./matlab_lib/libmx.lib\./matlab_lib/mclmcrrt.lib\

这个上面是什么意思呢,我是将matlab的库文件复制了一份到Qt的工程目录下,如下图
这里写图片描述
将要用的lib文件也拷贝到了工程目录下。
在.pro文件中添加上面代码即可。我采用的是相对路径法。. 代表是当前工程路径。
在main函数前面加上如下代码

#pragma comment(lib, "ws2_32.lib")#pragma comment(lib, "libeng.lib")#pragma comment(lib, "libmat.lib")#pragma comment(lib, "libmx.lib")

总结

最难点在于C语言中的矩阵转换为mxArray矩阵是怎么转换的,认真去理解。

1 0