一、Matlab与VC混合编程的实现方法
Matlab作为控制系统设计的一种通用工具,它可以和VC方便的进行连接。一般而言,Matlab与VC混合编程的实现方法主要有以下三种方法:(1)通过引擎(Engine),采用客户机服务器的计算模式,通过Window的ActiveX通道和Matlab进行连接。具体应用时,往往在VC中设计程序框架,以编译的程序作为前端客户机;通过调用Matlab引擎在后台实现与服务器的连接,实现动态通信(2)应用Matlab数学函数库,Matlab中包含了内容丰富的函数库,而且还提供了与VC的数学函数接口,用户可以方便的在VC的IDE(集成开发环境)中调用。(3)通过DLL实现VC与Matlab的混合编程。DLL是一个可执行的二进制文件。把很多通用的功能放在DLL中,可以供多个应用程序调用,这样可以很好的减少外部存储空间的占有量,并实现代码的共享[2]。在上述三种方法中,第一种方法对调用Matlab的工具箱很实用,所有在进行控制系统的设计和分析时,一般都是通过调用Matlab引擎(Engine)来实现的。本文主要介绍采用通过引擎(Engine)来实现VC与Matlab的混合编程。
二、配置编译器
要在VC中成功编译Matlab引擎程序,必须包含引擎头文件engine.h并引入Matlab对应的库文件libmx.lib、libmat.lib、libeng.lib。具体的说,打开一个工程后,做如下设置(以VC6为例):
1) 通过菜单工程/选项,打开设置属性页,进入Directories页面,在目录下拉列表框中选择Include files,添加路径:"C:\matlab\extern\include"(假定matlab安装在C:\matlab目录)。
2) 选择Library files,添加路径:C:\matlab\extern\lib\win32\microsoft\msvc60。
3) 通过菜单工程/设置,打开工程设置属性页,进入Link页面,在Object/library modules编辑框中,添加文件名libmx.lib libmat.lib libeng.lib。
以上步骤1)、2)只需设置一次,而步骤3)对每个工程都要单独设定,对于其它C++编译器如Borland C++ builder,设置大体相同,不再赘述。
三、编程实例
#include "engine.h"//matlab引擎"
double *coeff;
double delt[9];
delt[0] = log(1);
delt[1] = log(sqrt(2));
delt[2] = log(2);
delt[3] = log(sqrt(5));
delt[4] = log(sqrt(8));
delt[5] = log(3);
delt[6] = log(sqrt(10));
delt[7] = log(sqrt(13));
delt[8] = log(sqrt(18));
Engine *ep; //定义Matlab引擎指针。
if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。
{
MessageBox(NULL,"Engine message","Can't start Matlab engine!",MB_OK);
exit(1);
}
mxArray *x=NULL;//Matlab引擎中用的是mxArray型的数据
x = mxCreateDoubleMatrix(1,9,mxREAL);
memcpy((char*)mxGetPr(x),(char*)delt,9*sizeof(double));
engPutVariable(ep,"x",x);
mxArray *y=NULL;
y = mxCreateDoubleMatrix(1,9,mxREAL);
mxArray *result=NULL;
result = mxCreateDoubleMatrix(1,2,mxREAL);
//例一
mxArray *X=NULL;//Matlab引擎中用的是mxArray型的数据
X = mxCreateDoubleMatrix(1,9,mxREAL);//生成矩阵传递参数给matlab
memcpy((char*)mxGetPr(X),(char*)test,9*sizeof(double));
engPutVariable(ep,"X",X);//向matlab引擎参数
engEvalString(ep,"T=5*X;");//向matlab引擎发送命令
engEvalString(ep,"plot(X,T);");
//例二
…………
memcpy((char*)mxGetPr(y),(char*)Var,9*sizeof(double));//Var的值是有段程序计算的,未写出
engPutVariable(ep,"y",y);
engEvalString(ep,"p=polyfit(x,y,1);");
result = engGetVariable(ep,"p");//从matlab引擎里取数据
coeff = (double *)mxGetData(result);
H[i][j] = coeff[0];
//释放这些矩阵
mxDestroyArray(y);
mxDestroyArray(result);
mxDestroyArray(x);
engClose(ep); //关闭Matlab引擎
………………
错误问题:
关键问题在于matlab的版本上,要看这样一句错误提示:
F:\chen101903\chen101903Dlg.cpp(205) : error C2065: 'mxSetName_is_obsolete' : undeclared identifier
如果你到matrix.h中看mxSetName的声明会发现有这样一句
#ifndef matrix_h //判断是不是和V5兼容
#define V5_COMPT
#define matrix_h
.........................
#else
#define mxSetName mxSetName_is_obsolete//走这个预处理分枝就等于没有声明mxSetName()了
#endif
于是matrix.h里就相当于根本没有定义mxSetName这个东西.你只需要在
#include "matrix.h"
之前加一句
#define V5_COMPT 就可以了
形式如下:
#ifndef matrix_h
#define V5_COMPT
#define matrix_h