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的CC++函数库,或者借助Matlab的mcc编译器
生成CC++代码,然后嵌入用户的CC++程序。将CC
++
代码进一步编译为DLL或是EXE文件,可以应用于CC++语言之外的环境如VB,Delphi等。一些辅助软件如
Matcom也被广泛应用于混合编程。但是,上述方法都存在不少缺陷,编程的难度也较大,效率不高。MathWorks公司推出了两种强有力的混合编程工具:MatlabCOMBuilder和MatlabRuntimeServer。两种工具各有特点,RuntimeServer可以实现运行Matlab程序的最小环境,作为一个后台引擎提供服务,他没有将m
文件编译,而是解释执行的。与此不同,COMBuilder工具将Matlab程序编译成二进制COM组件,他实际上是以前编译CC++文件的完美扩展,简单高效的解决了以前混
合编程中存在的问题。由于推出较晚,目前缺乏其在VC
中应用的资料,本文在这方面进行了积极的探索。
2 MatlabCOM组件组件对象模型(COM,ComponentObjectModel)是
Microsoft提出的以组件为发布单元的软件开发技术。COM具有语言、平台无关的特性,可以方便软件的升级、定制与替换,是理想的软件应用方案。简言之,COM是一种CS标准,提供了一类应用程序接口,允许任何符合标准的程序访问。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%externinclude,%m%externincludecpp;lib添加%m%externlibwin32,%m%externlibwin32microsoftmsvc60。其中“%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);