利用Matlab引擎实现VC和Matlab的混合编程 江鹢 汤丽萍 边信黔 施小成 Implementation of VC and Matlab Complex Programming by means of Matlab Engineer Jiang Yi Tang Liping Bian Xinqian Shi Xiaocheng 美国MathWorks公司的Matlab具有强大的符号、数值计算、矩阵计算能力以及计算结果可视化能力,是一个功能强大的计算机辅助设计工具。但是由于Matlab在程序编写方面的一些局限性,使得它在处理许多问题时缺乏灵活性,而VC++在这一方面的功能却是十分强大的。因此在Windows环境下实现VC++和Matlab的混合编程将是一种极为强大的编程手段。它将更加有效地发挥VC++和Matlab各自的优点。
1 Matlab引擎简介 Matlab引擎采用客户机/服务器(Client/Sever)计算方式。实际应用过程中,把VC的C语言或C++语言的程序作为前端客户机程序,它从Matlab引擎接收数据信息,并与引擎传递命令的数据信息。 我们通过一种专门的对象类型-Matlab数组(mxArray)来完成Matlab引擎与VC之间的数据交换(Matlab语言仅用这种对象类型进行各种处理所有的变量都用Matlab数组(mxArray)来存储)。Matlab提供了语言下各种数组处理函数。函数说明详见帮助文件中的Application Program Interface。表1列出了几个常用的Matlab引擎的C语言调用函数。 表1 |
函数名 | 功能 |
engOpen | 打开Matlab引擎 |
engEvalString | 在Matlab引擎中执行输入的Matlab命令 |
EngPutArray | 将数据存入Matlab引擎 |
engGetArray | 从Matlab引擎中取出数据 |
engClose | 关闭Matlab引擎 |
2 VC和Matlab接口库的产生
要想在VC环境下利用Matlab引擎实现VC和Matlab的混合编程,必须要有两个Matlab库:libeng.lib和libmx.lib。这两个库并不存在于Matlab目录下,在Matlab\extern\include目录下只能找到这样两个动态链接库:libeng.dll和libmx.dll,所以我们的任务就变成了利用这两个动态链接库去生成我们所需要的libeng.lib和libmx.lib接口库了。 在这里我们要用到两个可执行文件:lib.exe和link.exe,以及一个动态链接库:mspdb60.dll。它们分别在目录:Microsoft Visual Studio\Vc98\bin\和Microsoft Visual Studio\common\MsDev98\bin\下,这三个文件缺一不可。 生成接口库的具体步骤如下:首先,我们将这三个文件分别从它们的目录下拷贝到下面的目录:Matlab\extern\include\,然后,进入MS-DOS环境,在\Matlab\extern\include\目录下分别执行下列命令以生成我们所需的接口库: lib /def:libeng.def/machine:ix86/out:libeng.lib lib /def:libmx.def/machine:ix86/out:libmx.lib 注意:lib后面一定要加一个空格。 这样我们就成功地生成了两个实现VC和Matlab混合编程所必需的接口库: libeng.lib和libmx.lib。3 VC和Matlab混合编程实例 按上述方法生成了接口库之后,只要将这两个接口库联入VC环境下的整个项目便可实现Windows环境下VC和Matlab混合编程。下面这个例子说明了如何在VC环境下实现与Matlab引擎进行数据通信,以及在VC环境下调用Matlab命令。 首先,在VC++6.0下新建一个基于对话框的应用程序VcMatlab,然后再添加一个按钮控件,并为按钮IDC-VC-MATLAB添加BN-CLICKED(鼠标单击)消息处理函数OnVcMatlab()。 #include ″stdafx.h″ #include ″VcMatlab.h″ #include ″VcMatlabDlg.h″ //包含该引擎头文件的路径 #include ″D:\Matlab\extern\include\engine.h″ void CVcMatlabDlg::OnVcMatlab() { int i; Engine *ep; mxArray *T=NULL, *SIN=NULL; double Time[101]; for (i=0; i<100; i++) { Time [i]=i; }//打开Matlab引擎,如在远程主机上打开, //应利用远程主机名加Matlab代替NULL if (!(ep=engOpen(Null))) { MessageBox(″Can′t start MATLAB engine″); exit(-1); } //利用程序数据创建一个实数型一维向量 T=mxCreateDoubleMatrix(1, 101, mxREAL); mxSetName(T, ″T″); memcpy ((char*)mxGetPr(T), (char*) Time, 101*sizeof(double)); engPutArray(ep,T); //在Matlab引擎中执行Matlab命令 engEvalString(ep,″SIN=sin(2*3.14*T/100.0);″); //利用Matlab引擎画图 engEvalString(ep,″plot(T,SIN);″); engEvalString(ep,″title(′正弦曲线′);″); engEvalString(ep, ″xlabel(′时间′);″); engEvalString(ep, ″ylabel(′正弦值′);″); Sleep(6000); //释放mxArray内存 mxDestroyArray(T); mxDestroyArray(SIN); //关闭Matlab引擎 engClose(ep); } 该程序在Windows环境下,成功地实现了VC和Matlab的混合编程,在VC的编译环境下,按matlab的格式画出了一条正弦曲线。 |