Matlab COM Server的VC++程序调用

来源 :电脑知识与技术 | 被引量 : 0次 | 上传用户:yy349764474
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:工程中往往需要VC 编写的程序进行大量的数学计算,如能在程序中使用Matlab的例程这些问题则能迅速解决。在Windows平台上Matlab 提供了两个实现这一目标的接口——Matlab Engine和Automation Server,两者在本质上都基于COM技术。引擎库通过其输出函数对用户屏蔽了底层的COM细节,这大大方便了使用。而使用自动化服务器就要使用COM的自动化接口IDispatch,不过MFC库的COleDispatchDriver类已使这一过程大大简化了。两种方式的差别主要体现在参数传递和返回值处理上,如文中代码所示。无论哪种方法,都可以将具有强大工程计算能力的Matlab接入VC 程序,从而快捷方面地解决许多数值计算和图形输出问题。
  关键词:Matlab外部接口;混合编程;VC ;COM;自动化
  中图分类号:TP311文献标识码:A文章编号:1009-3044(2008)36-2792-04
  Program with Matlab COM Server in VC
  SHEN Zhi-juan1, YANG Hei-lai1, WANG Shu-fen2, ZHANG Wei-min3
  (1.Mechanical Engineering and Automation Department, Beijing University of Aeronautics and Astronautics, Beijing 100083, China; 2.Computing Center, Hebei University of Science and Technology, Tangshan 063009, China; 3.Beingjing Aeronautic Manufacturing Reseach Center, Beijing 100024, China)
  Abstract: Programs written in VC sometimes need to do calculation intensive jobs, which can be solved swiftly if some Matlab function can be called inside the program. Matlab provides two methods to achieve this: Engine Library and Automation Server, both of which are based on COM. Engine Library made the custom COM interface IEngine transparent to the Client through its export functions while MFC class COleDispatchDriver encapsulates the detail of interacton with the COM Automation interface IDispatch. The given code in this article shows differences of the two method come mainly from the parameter passing and result retrieving process. With either method, Matlab can be linked into the program and thus make the calculation and figure output tasks be achieved faster and easier.
  Key words: matlab external interface; hybrid programming; VC ; COM; automation
  1 引言
  Matlab提供的編程语言——M语言——是以方便数值计算编程为目的设计的,所以其基本数据结构就是矩阵,且其变量的具体类型和大小可在执行时动态确定,这对编写数值计算程序提供了很大的便利。另外,由于M语言可直接调用Matlab提供的各种数学和面向工程应用的工具箱函数,所以使用M语言还可以迅速地解决许多计算量很大的工程问题。但另一方面,由于M语言是一种解释型编程语言,所以它的执行效率较低,另外其在开发应用程序界面和对外围设备的控制能力上也较差。另一方面,其他的编程环境,如VC ,则在这些方面提供了很好的支持,但如用其进行数值计算或解决工程问题又会非常不便。故如果对软件界面、外围设备控制、数值计算三方面都有较高的要求,一个理想的方案是在像VC 这样的编程环境中实现界面及外设控制功能,并在其中调用Matlab环境中的模块,如其工具箱函数,作为计算工具。
  在VC 程序中调用Matlab有两种方法:一是通过Matlab提供的引擎库(Engine Library),它的本质是一个拥有定制接口IEngine的COM服务器;二是通过Matlab提供的COM Automation Server。本文将首先介绍COM和Automation技术的原理和应用方法,之后介绍这两个接口,并随后给出在C 中使用两者的具体方法。
  2COM与Automation
  2.1 COM概述
  组件对象模型(Component Object Model,COM) 由Microsoft于1993年创建,它规定了dll、exe等应用模块之间进行交互的步骤和方法。在COM之前,一个应用程序(Client)如果要使用dll文件(Server)输出的功能就要使用Win32 API函数LoadLibrary,GetProcAddress,要使用exe文件(Server)输出的功能除了需使用相关的Win32 API函数外,还要使用基于Windows消息机制的DDE协议。COM则是Microsoft新推出的这些方法的换代品,它解决了不少在使用老方法时产生的问题,如他们本质上是面向过程的技术,使用起来比较零散复杂,且对系统来说,他们是无法管理的。COM则提供了一个面向对象的Server功能管理及Client/Server的通讯方法。但这需要应用编程者的配合,即COM不仅是Windows操作系统新增的一系列数据结构和函数,而且是一系列应用与系统交互方式的定义。
  在COM中,Server模块(dll或exe)要向系统注册其输出的COM类,即在注册表中保存COM类的GUID(Global Unique Identifier),Server模块完整的路径及文件名等相关信息。一个Server模块可拥有多个COM类。于是,Client只要向系统提供其所需COM类的GUID系统就能找到包含这个类的模块并加载它。在注册COM类的同时,Server还要注册每个COM类所包含接口(interface)的GUID。从功能上说,一个接口就是Server输出的一个功能单元,它由一组功能上密切相关的函数指针构成;而用C 语言表达,COM接口就是一个仅包含虚函数的结构体,它本质上是一个包含一个函数指针数组的内存结构,这一内存结构是由Microsoft定义的标准。Client则是通过GUID向系统提交自己的请求,通过获得由Server提供的接口指针来调用Server的输出函数[1]。
  事实上,接口是COM技术的核心要素,其最基础的接口是Microsoft定义的标准接口IUnknown,它包含QueryInterface、AddRef和Release三个函数,这些函数是Client与Server通信的基础。而所有其他的接口均需继承自IUnknown。这也是C 多态技术的一个应用。除了IUnknown,Microsoft还定义了许多其它接口,这些接口事实上是许多编程技术的底层基础,如IDispatch接口就是Automation技术的根本核心。同时需要说明的是,对其制定的大部分接口而言,Microsoft只是定义了接口的数据结构,接口函数功能的实现要由Server开发者完成。
  可见,COM是一个Client、Server和操作系统协力合作。从操作系统的角度看COM是一个记录COM类的方式和一组用于Client和Server通信的API函数。对Client来说COM是利用API向系统发出请求并利用接口指针使用COM类的功能。对Server来说则是利用API注册自己,实现所有接口函数,这包括由Microsoft定义的接口函数,如Server必须实现IUnknown接口的QueryInterface函数,其作用是为Client提供其所要求的所有接口指针。
  2.2 Automation概述
  由于接口本质上是一个包含一个函数指针数组的内存结构,这一内存结构是由Microsoft定义的标准,而所有支持COM的编译系统和语言对接口的处理都符合这一标准,所以通过COM,就可实现不同编译器、不同语言编写的应用顺利通信。但是仍有一个问题,就是想Visual Basic这样的解释性语言无法学习C 定义的接口。举例来说,如果一个C或C 程序要使用一个组件定义的接口IMath,它就需要声明接口的结构,如:
  struct IMath : IUnknown
  {
  virtual void Add(int a, int b) = 0;
  virtual void Multiply(int a, int b) = 0;
  virtual void Square(int a) = 0;
  };
  这样,在获得了接口指针,不妨叫pIMath,之后,就可以用“pIMath->Add(a, b);”这样的语句来使用Server的功能。但Visual Basic却不支持这样的语法,即它的解释程序无法以函数指针的形式学习新的接口定义。考虑到接口将会不断增长的事实,让Visual Basic把对所有接口的支持固化在解释程序中又是不可能的。所以,为了解决这类问题,Microsoft定义了IDispatch接口,其思想是,像VB这类语言的解释程序只需要支持IDispatch接口,就可以在执行时通过Server获得其需要函数的相关信息,从而完成调用。
  整个接口的机制是Server要为输出的函数分配一个数字ID和一个相对应的标识字符串。Client只知道标识字符串,为了调用相应的函数,Client在获取IDispatch接口指针后,先调用其函数GetIDsOfNames()得到和标识字符串相对应的数字ID,再调用IDispatch的函数Invoke(),该函数专门负责根据输入的数字ID找到Client要求的函数,并调用它。Invoke()在调用函数时需要传递参数,而参数格式是无法由解释程序预知的,所以Invoke()使用了一种特殊的数据类型VARIANT来解决这一问题。VARIANT是一个结构体,它可以表示任何类型的数据。VARIANT主要由两部分组成,一是标识数据类型的vt,二是存储实际数据的union结构。函数的输入参数就被存储在一个VARIANT数组里被传递给Invoke。当然,之后解析各个变量并传递给输出函数的任务就交由Invoke()完成了。函数的返回值同样是以VARIANT形式回传的。这样,就解决了高级语言使用COM组件的问题。
  所以,自动化(Automation)是建立在COM基础上的。一个自动化服务器实际上就是一个实现了IDisPatch接口的COM组件。而一个自动化控制器则是一个通过IDisPatch接口同自动化服务器进行通信的COM客户。
  3 Matlab 提供的COM Server接口
  由于出现了Automation技术,访问COM组件就有了两种方式:①通过普通的自定义的COM接口访问组件;②通过调度接口IDisPatch访问组件;如果一个组件同时实现了这两种接口,则称为双重接口,那么客户就可自由的选择其中的一种方式访问组件的功能。Matlab就提供了这两种接口。
  3.1 IEngine 接口
  IEngine是Matlab提供的定制接口,但通常在程序中不会直接使用它,而是使用Matlab提供的引擎庫(Engine Library)函数。事实上,COM Server及其接口IEngine可看作是引擎库在Windows平台上的实现手段。当然,也可以把引擎库看作Matlab为方便IEngine的使用而提供的函数库。在使用引擎库时,完全不需要COM的知识,只需要把它看成一个非标准的C语言静态函数库即可。
  引擎库共输出了9个函数,通过它们可以方便的开始和结束与Matlab Server的对话,设置命令窗口(缺省状态是显示命令窗口),与Matlab的工作空间交换变量,执行任何可在Matlab命令行执行的命令。使用引擎库和直接在Matlab命令行输入的方法是极为类似的。
  3.2 IDispatch 接口
  IDispatch是Matlab为Visual Basic,C#等语言提供的接口,但在C 程序中也可以使用,只不过,这需要进行较多和COM相关的编程。如果使用VC 提供的MFC类COleDispatchDriver来使用Matlab 自动化服务器,则可以大大简化这一过程。这些内容后面会详细讨论。
  通过IDispatch接口获得的函数功能和引擎库类似,但功能更丰富更灵活些。例如,如果要调用统计工具箱的方差计算函数求某一双精度数组的方差,使用引擎库函数的流程必须是先通过engPutVariable()将数组存入Matlab,比如起名叫“a”;再用engEvalString()命令执行一条语句“b = std ( a )”,这在执行命令的同时又在Matlab里建立了变量“b”;最后通过engGetVariable()将变量"b"取回。Matlab的自动化服务器则除了拥有支持上面流程的函数外,还提供了另一种可能性,即只需调用函数Feval()就可以了,因为Feval()可同时接受函数名,参数作为输入,并将Matlab的计算结果输出。
  4 Matlab COM 接口的VC 调用
  在VC 中使用Server的关键问题有两类,一类是如何启动和释放Server,另一类是如何与Matlab进行数据交互。下面将分别针对这两方面,以一个具体的问题——方差的计算,待计算的数据保存在变量double Array[20]中——为例,说明调用Matlab 两种COM接口的具体操作。下面的代码均经过实际测试使用,其环境为WindowXP,Visual C 6.0和Matlab 7.4.0。
  4.1 Server的启动和释放
  4.1.1 引擎库
  使用引擎库在创建工程时不需要特别设置,但之后第一要在源文件中包含engine.h,它其中声明了引擎库函数的原型。engine.h中还包含头文件matrix.h,其最主要的内容是定义了数据类型mxArray及对它进行操作的函数原型。mxArray类型是许多引擎库函数的参数类型,它是C 程序和Matlab进行数据交互的工具。而matrix.h中又包含tmwtypes.h,这一头文件中也定义了一些数据类型。三个头文件的路径均为Matlab安装目录下的extern\include。将engine.h包含入源文件有三种方法,其一是在源文件中包含完整的路径和文件名,如“#include "D:\matlab\extern\include\engine.h”;其二是仅包含文件名,但把上述三个头文件全部拷贝到工程目录中;其三也是只包含文件名,但要在VC 6.0的Tool菜单的Option命令对话框的Directory选项卡中,把头文件所在路径添加到include搜索路径中。这之后,还要为工程加入两个库文件——libeng.lib和libmx.lib,其中libeng.lib实现了引擎库函数,而libmx.lib则实现了操作mxArray需要的各个函数。它们路径均为Matlab安装目录下的extern\lib\win32\microsoft。具体操作为右键单击VC 6.0左侧Workspace里FileView的工程文件,在弹出菜单中选择“Add File to Project”,之后在弹出的对话框中转到上述目录后将文件过滤设为“Library Files”就可以选择所要的库文件了。为方便代码的移植,则可以先将上述文件复制到工程所在目录再进行添加。
  在做好这些准备工作后,就可以正式使用引擎库了。引擎库启动可使用如下代码:
  Engine *ep;
  if (!(ep = engOpen("\0"))) {
  fprintf(stderr, "\nCan’t start MATLAB engine\n");
  return;
  }
  结束与Matlab的对话可使用:
  engClose(ep);
  4.1.2 自动化服务器
  在C 程序中直接用Win32 API操作自动化服务器是比较繁琐的,所以笔者对自动化服务器的操作是通过MFC的COleDispatchDriver类完成的。这就要求在创建工程时要加入对MFC类的支持。之后,启动Class Wizard,单击其新建类按钮中的“从类库(type library)”命令从而打开“从类库导入”为标题的对话框。在对话框中转入Matlab安装目录下的bin\win32文件夹,选择其中的mlapp.tlb文件就可以生成继承自COleDispatchDriver类的DIMApp类。
  完成上述工作,就可用下面代码启动Matlab自动化服务器:
  DIMLApp MatlabAuto;
  COleException *e = new COleException;
  try{
  if (!MatlabAuto. CreateDispatch("matlab.application", e))
  throw(e);
  }
  // Exception handling code.
  其中,函数CreateDispatch()是从基类COleDispatchDriver继承的。结束自动化服务器可用如下代码:
  MatlabAuto.ReleaseDispatch();
  函数ReleaseDispatch()也是从基类COleDispatchDriver继承的。
  4.2 数据交换
  无论是采用哪种调用方式,Client都需要一种中间数据类型来与Matlab交互数据。当要把参数传递给Matlab时,Client需要先把自己的数据转换成中间类型;当从Matlab获取结果时,Client要从中间类型中提取原始数据。对引擎库来说,这种中间类型是mxArray;对自动化服务器来说,这种中间类型是VARIANT。下面通过代码来说明这两种方式。
  4.2.1 引擎库
  使用引擎库的代码如下:
  double standard_deviation = 0;
  // Create a variable for our data
  mxArray *a = mxCreateDoubleMatrix(1, 20, mxREAL);
  mxArray *b = NULL;
  memcpy((void *)mxGetPr(a), (void *)Array, sizeof(Array));
  // Place the variable a into the MATLAB //workspace
  engPutVariable(ep, "a", a);
  // Evaluate function
  engEvalString(ep, "b =std(a);");
  // Get Result
  b = engGetVariable(ep, "b");
  standard_deviation = mxGetPr(b)[0];
  cout << "The standard deviation is " << standard_deviation << endl;
  // Release memory
  mxDestroyArray(a);
  a= NULL;
  mxDestroyArray(b);
  b= NULL;
  4.2.2 自动化服务器
  使用自动化服务器的代码如下:
  double standard_deviation = 0;
  VARIANT a; // 用于向Matlab传递参数
  VariantInit(
其他文献
摘要:小学生时期正处于儿童关注社会、思考生活的心理年龄,对生活和周围发生的一切充满好奇与渴望,如何以课堂教学为轴心,为学生展示社会生活的各个领域,全方位将家庭、社会生活与小学语文教学相结合成为我们目前关注的主要问题。  关键词:小学语文教学生活化  引言  生活是构成语文教育和教学内容的源泉,是人们进行语文学习最丰富的资源库,随着语文教育事业的不断改革与发展,越来越多的教育工作者认识到语文学习活动
文学是在语言文字最初的交流和记录功能之上发展、升华出来的思想情感的表达方式,是人们对客观世界的认识和主观感受的外在流露。由北京大学出版社出版,涂险峰、张箭飞主编的《外国文学》一书,按照文学本身的发展规律,分别以时序和国家地区为标准,遴选了一批在历史上各个时期的各个民族和地区最具代表性的作家和作品,全方位地勾画出一幅世界文学发展地图,并提炼出其中的精华部分呈现给读者。本书是中国文学工作者和爱好者了解
书名:语文教学与思维创新  作者:李媛  出版社:天津科学技术出版社  出版时间:2019年  ISBN:9787557664534  定价:50元  语文学科不仅是基础学科,而且是培养学生创新思维的重要学科。随着教育改革的不断深化,语文教学中创新思维的应用已经得到人们的认可与重视。李媛著、天津科学技术出版社出版的《语文教学与思维创新》一书,结合语文教学现状及中小学生的思维特点,从理论与实践两个层
摘要:文章首先对基于PDA的导航系统的现状进行分析,通过对几种GPS定位技术的对比,得出各个定位技术的优差点。随后深入剖析了基于PDA的导航系统的结构框架特点:平台简单,模块可定制,对于非专业人员操作简单。最后通过对平台的实用性分析及相关测试,实现了系统的部分导航功能。  关键词:GPS;导航系统;Wince;定位  中图分类号:TP317文献标识码:B文章编号:1009-3044(2008)36
摘要:该文根据无线Mesh网络节点间的均衡特性,研究了网络在TDD方式下时延问题的影响。参考GSM网络中的TA(时间提前量)的方法,分析了TA方案在Mesh结构下的不适应性,以及提出了基于TA思想的改进方案使之适应Mesh特殊的网络结构。  关键词:无线;Mesh;时延碰撞;TDD;TA时间提前量  中图分类号:TP393.02文献标识码:A文章编号:1009-3044(2008)36-2621-
“语文主题学习”强调“简简单单教语文,轻轻松松学语文”,强调“一课一得”,强调“语文是学生读出来的,不是老师讲出来的”,倡导课内海量阅读,实现了课外阅读课内化,课内阅读主题化,自主阅读生活化。但是一些地区的教师在初期备课时,常常只关注到单篇课文,对于统编教材的编者意图与学生的实际学情缺乏观照,对于单元整体教学没有规划和安排,没有语文能力的建构意识;将课外阅读纳入课内,又常常觉得时间不够,主要问题在
我国习作教学一直以来问题较大,引起很多专家学者的关注,理论成果颇丰,但是实践层面还是不能完全摆脱文章写作的羁绊。文章写作关注文章是什么样的,忽视文章是怎么写的,即忽视写作过程。另外,在课堂教学中,从教的层面来看,教师一般是从技法、范文和情境创设等方面去教学,问题症结在于缺乏过程指导。从学的层面来讲,学生刚开始学习习作,如果缺乏必要的过程指导,不知道写什么、怎么写,更不能感知如何写才好。同时,统编本
摘要:该文介绍了软交换技术,分析了软交换在3G核心网中的应用,介绍了软交换在3G核心网中应用的种种优势。虽然基于软交换组建3G移动核心网有着许多优势,但目前的解决方案大多处于实验,尚为形成大规模应用,许多问题仍然需要继续关注,如QoS、安全性问题等。  关键词:软交换;3G;应用  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)32-1060-01  In the 3
《精卫填海》作为《山海经》中一篇描写人物悲怆经历的神话故事,被编入了统编教材四年级上册。这是一篇人物类文言文,内容简短,语言凝练,适合小学生阅读学习。教学《精卫填海》时,教师要以小学语文统编教材语文知识、人文素养双线要求为指导原则,引导学生识字寻源、正音解词、熟读成诵,在畅读文言与复述感悟文化中促进知识与素养的双提升。  一、识字寻源,说文解字  教学《精卫填海》时,教师要抓住音、形、义,让学生读
摘要:本文在介绍数字校园和GIS技术基础上,研究GIS技术在数字校园建设进程中所起的作用,研究基于GIS技术的数字校园体系结构和特点。  关键词:GIS;数字校园  中图分类号:TP311文献标识码:A 文章编号:1009-3044(2008)33-1301-02  The Research for GIS Digital School System  LI Yi-ming   (Hunan In