Matlab的混合编程技术

  • 格式:pdf
  • 大小:121.55 KB
  • 文档页数:3

基于COM的VC与Matlab的混合编程技术王晓春,曹 鸣,罗永新(东南大学自控系 江苏南京 210096)

摘 要:阐述了Matlab新推出的混合编程工具COMBuilder的应用方法,深入分析了VC实现COM的原理和运行机制,并由此通过实例说明了一种新的脱离Matlab环境的混编技术的实现。关键词:COM;VC;Matlab;混合编程中图分类号:TP312 文献标识码:B 文章编号:1004373X

(2004)

1901602

MixedProgrammingTechniqueUsingVCandMatlabBasedonCOMWANGXiaochun,CAOMing,LUOYongxin(AutomationDepartment,SoutheastUniversity,Nanjing,210096,China)

Abstract:ThearticlediscussestheapplicationofamixedprogrammingtoolCOMBuilderanddeeplyanalyzestheprincipleand

mechanismofimplementingCOMusingVC1TherealizationofanewmixedprogrammingtechniquedispensingwithMatlabenvironmentisalsodiscussedbyexamples1Keywords:COM;VC;Matlab;mixedprogramming

收稿日期:20040520

1 引 言Matlab是MathWorks公司推出的工程计算软件,他以强大的矩阵运算能力为基础,同时提供多种学科领域的工具箱,现已发展成为世界上最优秀的数学应用软件。由于语言的平台局限性,Matlab程序无法脱离Matlab环境而运行。因此,如何利用Matlab强大的计算绘图功能和众多完善的算法,并与高级开发语言如VB,VC结合,各取所长,提高效率,开发脱离Matlab环境的应用程序,一直是科研工作者研究的热点问题。现有的脱离Matlab环境的混合编程技术主要是借助Matlab的C󰃗C++函数库,或者借助Matlab的mcc编译器

生成C󰃗C++代码,然后嵌入用户的C󰃗C++程序。将C󰃗C

++

代码进一步编译为DLL或是EXE文件,可以应用于C󰃗C++语言之外的环境如VB,Delphi等。一些辅助软件如

Matcom也被广泛应用于混合编程。但是,上述方法都存在不少缺陷,编程的难度也较大,效率不高。MathWorks公司推出了两种强有力的混合编程工具:MatlabCOMBuilder和MatlabRuntimeServer。两种工具各有特点,RuntimeServer可以实现运行Matlab程序的最小环境,作为一个后台引擎提供服务,他没有将m

文件编译,而是解释执行的。与此不同,COMBuilder工具将Matlab程序编译成二进制COM组件,他实际上是以前编译C󰃗C++文件的完美扩展,简单高效的解决了以前混

合编程中存在的问题。由于推出较晚,目前缺乏其在VC

中应用的资料,本文在这方面进行了积极的探索。

2 MatlabCOM组件组件对象模型(COM,ComponentObjectModel)是

Microsoft提出的以组件为发布单元的软件开发技术。COM具有语言、平台无关的特性,可以方便软件的升级、定制与替换,是理想的软件应用方案。简言之,COM是一种C󰃗S标准,提供了一类应用程序接口,允许任何符合标准的程序访问。MatlabCOMBuilder110于2002年6月在Matlab615版中推出,他编译的COM组件实现了标准的IDispatch接口,提供了对自动化(Automation)的支持。

自动化对象公开了方法和属性,方法是指自动化对象提供的功能服务,类似于类的成员函数;属性是指自动化对象的数据特征,类似于成员变量。另外,为了实现组件对象与客户端的通信,增强了程序的交互性,Matlab组件也支持事件。事件是回调函数,由客户端实现,事件发生时,组件会自动调用实现的客户端事件函数。使用之前要用mbuild命令进行系统配置,本文中选择VC610作为编译器。实际上,COM组件在生成过程中先利用mcc命令调用Matlab编译器,然后调用VC编译器。下面通过一个例子说明COMBuilder的用法。(1)编辑3个函数m文件如下

:

①drawsin1m,在[0,x]内画正弦曲线。61

自动化技术王晓春等:基于COM的VC与Matlab的混合编程技术© 1995-2005 Tsinghua Tongfang Optical Disc Co., Ltd. All rights reserved.functiondrawsin(x)globalA;t=0:0101:x;plot(t,A3sin(t))

②datenow1m,n次获取当前时间。functiondatenow(n)fori=1:neventfun(datestr(now));

pause(1);

end

③eventfun1m,事件回调函数,需要在客户端程序(VC)中实现。

functioneventfun(i)%#event

i

(2)键入comtool命令启动COMBuilder,在

Setting

中设置Compontentname为MatlabCom,ClassName为MatlabClass并在ComplierOption中选中UseHandleGraphicsLibrary,确定。(3)在

ProjectFile中选中MatlabClass,将上述m文

件加入编译即可。通过菜单命令ComponentInfo查看编译完成的组件信息:类MatlabClass包括方法datenow()与drawsin()

,

属性A,事件eventfun()

。可以看出,只需将所需的功能用

m文件实现即可,COM组件的生成非常简单:m文件中的函数被编译为方法,全局变量编译为属性,包含注释“%

#event”的函数则被声明为事件。至此,MatlabCom

组件

编译完成,可以在各种语言环境下调用。

3 VC与Matlab混合编程COMBuilder编译的组件实现了自动化接口,在VB或VJ中使用非常方便,因为这些语言已经对COM的实现细节做了封装。VC功能强大,效率较高,但他实现比较复杂,需要对COM机制有深入的了解。作为最基本的Windows开发工具,Win32SDK中提供了COM库的API函数和标准接口。在此基础上,VC包装形成了两套类库:

MFC库和ATL模板库。MFC库提供了全面的COM支持:在CCmdTarget类中实现了COM组件最重要的IUnknown接口,从而覆盖了主要的MFC类;通过宏实现了接口映射表机制;对类厂的支持等。用VC实现客户端程序,调用MatlabCom组件,主要步骤如下:

(1)用MFCAppWizard新建对话框工程VcMatlab。

在Tool→options→directroy设置路径:include添加%

m%󰃙extern󰃙include,%m%󰃙extern󰃙include󰃙cpp;lib添加%m%󰃙extern󰃙lib󰃙win32,%m%󰃙extern󰃙lib󰃙win32󰃙microsoft󰃙msvc60。其中“%m%”为Matlab安装目录。

(2)通过ClassWizard→AddClass→

Fromatype

Library将上面编译好的组件MatlabCom_1_01dll加入工程,在ClassView中多了两个类IMatlabClass与IMatlabClassEvents,均派生自COleDispatchDriver,他是MFC提供的一个封装类,主要用于自动化对象的客户调用IDispatch::Invoke()

函数。

IMatlabClass包括方法datenow()与drawsin()。由于

不能直接访问COM对象内成员变量,另有方法SetA()

GetA()用来存取属性。方法SetMWFlags()与

GetMWFlags()用来设置数据格式。

用OleViewer工具查看组件的IDL文件,

_IMatlabClassEvents的接口属性为“source”,表明此为一出接口。生成的类_IMatlabClassEvents可以删掉,因为对于事件的响应,需要在客户端实现这一接口,当事件发生时用来响应组件的消息。本质上,客户端的接收器也是一个COM对象,但他位于客户程序内部,不需要通过COM

库即可直接创建。实现接口的类必须派生自CCmdTarget,

此处用CVcMatlabDlg类实现。在类CVcMatlabDlg定义中添加代码:

DECLARE_DISPATCH_MAP()DECLARE_INTERFACE_MAP()afx_msgvoideventfun(LPCTSTRstrtime);

在类实现VcMatlabDlg1cpp文件中添加代码:

BEGIN_DISPATCH_MAP(CVcMatlabDlg,CDialog)

DISP_FUNCTION(

CVcMatlabDlg,"eventfun",

eventfun,VT_EMPTY,VTS_BSTR)END_DISPATCH_MAP()BEGIN_INTERFACE_MAP(CVcMatlabDlg,CDialog)

INTERFACE_PART(

CVcMatlabDlg,DIID

IMatlabClassEvents,Dispatch)END_INTERFACE_MAP()

MFC利用嵌套类与映射表机制实现COM接口,所有的细节被巧妙地隐藏在上述宏的背后。添加事件的实现:

voidCVcMatlabDlg::eventfun(LPCTSTRstrtime){AfxMessageBox(strtime

);}

(3)在CVcMatlabApp::InitInstance()中添加

AfxOleInit(),类CVcMatlabApp的构造函数中添加EnableAutomation()。在文件stdafx1h中添加#include,VcMatlabDlg1cpp添加#include

"matlabcom101h"并定义接口ID:DIIDIMatlabClass

Events和CLSIDMatlabClass,不同机器生成的ID不同,可以参照matlabcom_idl_i1c文件中的定义。(4)对话框添加按钮

IDC_BUTTON,在其响应函数

OnButton()添加代码

:

IMatlabClass3pMatCls=newIMatlabClass();

pMatCls->CreateDispatch(CLSID_MatlabClass);