《电子技术应用》
您所在的位置:首页 > 其他 > 设计应用 > 基于MATCOM的MATLAB与VC混合编程技术研究
基于MATCOM的MATLAB与VC混合编程技术研究
吴高峰1,李熙莹2
摘要: 研究了基于MATCOM的MATLAB与VC混合编程技术,提出了一种简便的设置MATCOM环境的方法,介绍了MATCOM提供的一个方便调试工具——矩阵查看器及其具体使用方法。结合实例,详细介绍了基于MATCOM的混合编程的实现途径,对扩展MATCOM的功能提出了一种独到的解决办法。
Abstract:
Key words :

  摘 要: 研究了基于MATCOM的MATLAB与VC混合编程技术,提出了一种简便的设置MATCOM环境的方法,介绍了MATCOM提供的一个方便调试工具——矩阵查看器及其具体使用方法。结合实例,详细介绍了基于MATCOM的混合编程的实现途径,对扩展MATCOM的功能提出了一种独到的解决办法。
  关键词: MATCOM;MATLAB;VC;混合编程

   MATLAB是MathWorks公司推出的数学软件,它将数值分析、矩阵计算、信号处理、数据采集和图形显示结合在一起,包含大量高度集成的函数可供调用。现在,MATLAB几乎在各个领域都得到了广泛的应用,也取得了巨大的成功,被称为第四代编程语言。
  但是MATLAB使用的是解释性语言,这大大限制了它的执行速度,而且用MATLAB开发的程序只局限于MATLAB运行环境而不能作为商业软件。
  VC作为Windows平台下主要的应用程序开发环境之一,能方便实现软件开发,但在工程计算及可视化方面,与MATLAB相比编程显得复杂很多,因此,将VC与MATLAB混合编程,必将为软件开发带来便利。
  本文介绍基于MATCOM的混合编程方法。示例中用到的软件为MATLAB R2009A和VC 6.0。为了便于叙述,用VC6.0新建一个基于对话框的程序TestMatcom。
1 MATCOM简介
    MathTools公司有一系列的产品,包括MIDEVA、MATCOM、Visual MATCOM、Matrix 。其中Matrix 是所有产品的核心,它是一个C++数学图形图像库,里面包含了约600个经过严格测试的函数,是实现将M文件转化为C++文件的基础。MATCOM是基于Matrix 的一个编译器,Visual MATCOM可以看成是一个集成到VC环境中的MATCOM。而MIDEVA是M文件的解释器和集成开发环境,它通过一个完整而强大的开发和运行M文件的环境包含并拓展了MATCOM的功能,可以和MATLAB相媲美。为了方便,通常将MathTools公司的这些产品统称为MATCOM。本文在不引起混淆的情况下不作区分。
2 MATCOM的安装与配置
  MATCOM的安装与普通Windows程序的安装过程类似,可参考文献[1]、[2]所述。成功安装后,在目录C:\matcom45\lib下可找到matlib.h及v4501v.lib这2个文件,在Windows操作系统的system32目录下可找到v4501v.dll和ago4501.dll这2个文件。将这4个文件拷贝到TestMatcom工程中再做如下配置即可:
  (1)在VC的FileView标签中的Resource Files目录上点击右键->Add Files to Folder->文件类型选择“Library Files(.lib)”->选中v4501v.lib ->点击“OK”即添加成功。
    (2)在需要使用MATCOM函数的文件中添加#include "matlib.h"。本文示例在TestMatcomDlg.cpp中添加。
    (3)在使用MATCOM的函数之前,添加初始化语句:initM(MATCOM_VERSION)。本文示例在void CTestMatcomDlg::OnPaint()函数中添加。
    (4)在使用MATCOM的函数之后,添加释放资源语句:exitM()。本文示例也在void CTestMatcomDlg::OnPaint()函数中添加。
    为了使Visual MATCOM可用,也需做相应的配置,参考文献[1]、[3]介绍了配置的过程,本文从略。
3 巧用矩阵查看器
  安装完Visual MATCOM之后可以看到Visual MATCOM工具栏中有个眼镜按钮,这个就是矩阵查看器。在调试模式下可以通过它查看MATCOM矩阵的值,这对VC程序调试是非常方便的。在VC中,指针变量和数组尤其是二维及以上的指针变量和数组的元素值是不方便查看的。有了这个工具,就可以将需要查看的指针变量或数组的值传递给MATCOM矩阵,然后在矩阵查看器中查看[3]。具体的查看方法是:在相应位置设置断点,当VC程序运行到断点停下后,点击矩阵查看器按钮,然后在矩阵名对话框里输入矩阵名,并点击Reload按钮,矩阵的内容即可显示出来。另外,为了使得矩阵查看器能在程序中起作用,需要在VC程序中添加:unsigned int mlibpr=mt_set_MT(0)。
  示例:
  /*定义1个二维数组*/
    double a[2][3]={1,2,3,4,5,6}; 
    /*定义1个Mm 矩阵,
    并初始化为2行3列,元素都为0*/
    Mm ma=zeros(2,3); 
    /*将数组元素复制到ma中*/ 
    memcpy((char*)ma.addr( ),(char*)a,6*sizeof(double));
4 混合编程的实现
  混合编程有不同的实现途径,本文将其分为二大类。
4.1 将M文件转化为C++代码
  M文件可分为脚本文件和函数文件两大类。这两者的混合编程实现步骤略有不同。现以2个示例说明。
    例1:
      %wires.m
      n=1000;
      t=inspace(0,2*pi,n);
      x=sin(t).*sin(2*t).*sin(3*t);
      y=cos(5*t).*cos(7*t).*cos(11*t);
      plot(x, y);
  双击桌面上的MIDEVA图标打开MIDEVA,然后在MIDEVA菜单栏中选File->Compile to exe,在弹出的Go command对话框中通过浏览选择wires.m这个文件,然后点击OK.转化成功后可以在C:\matcom45\Debug下找到wires.cpp这个文件。打开这个文件,可以看到内容为(删去不需要的代码,注释为笔者添加,欲全面了解M文件与其对应的CPP文件的关系,可以参考文献[2]):
  //Mm为处理矩阵的类
   Mm n; Mm t; Mm x; Mm y;
   n=1000.0; 
  t=linspace(0.0,2.0*pi,n);  
   x=times(times(sin(t),sin(2.0*t)),sin(3.0*t)); 
    /*MATLAB的点乘操作在VC里面通过times函数实现。*/
  y=times(times(cos(5.0*t),cos(7.0*t)),cos(11.0*t));
  plot((CL(x),y));/*输入参数个数不定时,需用CL函数。注意y不用加CL()*/
   可以看出,经MATCOM转化后的C++代码和M代码几乎句句对应,可读性强。将以上内容拷贝到void CTestMatcomDlg::OnPaint()函数中,编译运行即可得到所需的结果。
    例2:
      %CreateMagic.m
    function result=CreateMagic(n)
      result=magic(n);
  用MATCOM成功转化后可以在Debug目录下找到CreateMagic.cpp和CreateMagic.h这2个文件。将其添加进TestMatcom工程中并在TestMatcomDlg.cpp中添加1句:#include“CreateMagic.h”同时在消息响应函数中添加代码:“Mm a=5; Mm b=CreateMagic(a);”可验证b为5×5的魔方阵。若编译不通过 ,可尝试在CreateMagic.cpp文件中添加#include "stdafx.h"。
4.2 将M文件转化为DLL
  出于代码保密等原因,有时需要将M文件转化为DLL以供其他程序调用,这时可以利用MATCOM的Compile to dll功能来实现。
    示例:
       %Exchange2.m
       function[c,d]=Exchange2(a,b)
       c=b;
       d=a;
    通过File->Compile to dll将该M文件转化为dll,在Debug目录下可找到Exchange2.lib和Exchange2.dll这2个文件,将其放入TestMatcom工程目录下并在TestMatcomDlg.cpp中添加以下代码:
    #pragma comment(lib, "Exchange2.lib")
    extern "C" int DLLX_stdcall Exchange2_v(char* emsg, int nlhs, Mm* plhs[ ], int nrhs, Mm* prhs[ ]); 
  MATCOM将M文件里面的函数Exchange2转化成了Exchange2_v函数,该函数的第1个参数emsg用于传递1个消息字符串,可赋值为NULL;第2个参数nlhs是Exchange2函数定义的输出参数的个数;第3个参数plhs[]是指向输出参数的指针数组;第4个参数nrhs是Exchange2函数中定义的输入参数的个数;第5个参数prhs[ ]是指向输入参数的指针数组。
    在消息响应函数中添加如下代码:
  Mm a, b, c, d;
  a=zeros(1,3);
  b=ones(1,3);
  b.r(1,2)=100;    /*将矩阵b的第1行第2列元素赋值为100  */ 
  Mm* Input[2]={&a,&b};
  Mm* Output[2];          //不用为其分配空间
  //调用dll函数
  Exchange2_v(NULL, 2, Output, 2,Input);
    //查看第1个输出参数的结果
  Mm lookOutput1=*Output[0];
  //查看第2个输出参数的结果
  Mm lookOutput2=*Output[1];
  即实现了调用dll里的Exchange2_v函数。
    MATLAB与C++混合编程的方法有8种之多。但是基于MATCOM的混合编程方法简便易行,生成的代码可读性很好,笔者认为是实现MATLAB与VC混合编程的最优途径。在实际工程应用当中,经常会调用到很多的MATLAB工具箱函数,而对于MATLAB 5.3版本以后新增的函数或者MATLAB工具箱函数,MATCOM并没有提供相对应的函数。这时可以采用的解决办法是:将用到的函数对应的M文件(可从MATLAB安装目录中获得)拷贝到与待转化的M文件同一个目录下,MATCOM会自动进行关联分析并转化。转化完成后只需将生成的头文件和源文件一起放到VC工程中就可以了。笔者在车牌识别系统中采用这种方法有效缩短了系统开发的周期和效率。
参考文献
[1] MathTools Ltd. MIDEVA, MATCOM & visual MATCOM installation guide (V4.5 release).1999.
[2] 刘维.精通Matlab与C++混合程序设计[M].(第2版). 北京:北京航空航天大学出版社,2008:257-315.
[3] 罗蛟龙,张鹏,张维竞.Visual C++下强大的科学运算函数库—MATCOM之Matrix [J].计算机工程,2000,
26(12):152-154.
[4] MathTools Ltd. Matrix user’s guide(V4.5 release). 1999.

此内容为AET网站原创,未经授权禁止转载。