m文件转换示例—Test1

本节以一个线性方程组的求解过程为例,介绍通过MATcom实现VC对MATLAB m文件的调用。

(1)编写MATLAB m文件“LineEq.m”,用于求解线性方程组的解;

(1)编写MATLAB m文件“LineEq.m”,用于求解线性方程组的解;

MATLAB m文件清单:

code.matlab
%Slove linearEquation: A*X=B
function X = LineEq(A, B)
X = A\B;

(2)创建VC工程“Test1”;

运行VisualC++并单击File->New,打开Project对话框来创建各种VC工程。这里以较为简单的控制台程序为例,选取Win32 Console Application (图3-5,其它程序基本相同)。在loctation编辑框中输入欲创建工程的保存路径,在Project name编辑框中输入工程名如“Test1”,单击OK进入下一步工程设置对话框,选取“A single application”,单击Finish完成工程创建工作。

Document Image

图3-5 创建Test1工程

(3) 转换m文件“LineEq.m”;

单击Visual MATcom工具栏上的m++图标,选择保存过的MATLAB文件LineEq.m进行转化。如果看到的转化信息提示没有错误就可以观察到此时在FileView标签中多了m-files、C++files created from m-files、MATrix<lib>和External Dependencies等文件夹(图3-67)。在相应的文件夹下增加了LineEq.m、LineEq.cpp、v4501v.lib、LineEq.h和matlib.h等文件。表明m文件转换成功;否则,表明m文件中存在错误,可双击m-files\LineEq.m进行修改,再重新转化直到没有错误报告为止。

Document Image

图3-6 LineEq.m文件转换结果

LineEq.m经转换后所生成的LineEq.h和LineEq.cpp文件,分别进行了LineEq函数(以m文件名为函数名,建议用户不修改此函数名,若必须修改时,要注意函数名在相应文件中的统一)和函数体的定义。打开LineEq.h,从程序清单中可知LineEq函数有两个参数,分别为A和B,与LineEq.m文件中的输入参数A和B相对应,其数据类型为Mm。Mm数据类型是MAThtools公司利用MATcom技术开发的矩阵数学库matrix<lib>中定义的基本数据类型,是一种双精度的matrix数据,它可以是复数矩阵、实数矩阵、稀疏矩阵甚至n维矩阵;LineEq函数返回值也为Mm类型。

code.vc
/////////////////////////////////////////// LineEq.h清单
#ifndef __LineEq_h
#define __LineEq_h
Mm LineEq(Mm A, Mm B);
#endif // __LineEq_h
//////////////// 结束

打开LineEq.cpp,从程序清单中可知,LineEq.cpp包括两部分:头文件中包含了”matlib.h”、 hdrstop和"LineEq.h"三个文件。其中”matlib.h” 是将MATcom数学库包含至文件中,在使用此包含语句前,须按3.1中方法在VisualC++中设置MATcom调用环境;

code.vc
pragma hdrstop

"LineEq.h"作用与一般的C++程序相同,是函数定义头文件,为程序提供转换后C++代码中使用的数据类型、函数原型及常量等信息。

code.vc
///////////////////////////////////////////////////////// LineEq.cpp清单
 //////////////////////////// 头文件
#include "matlib.h"
  #pragma hdrstop
  #include "LineEq.h"
  ///////////////////////// LineEq函数体
  Mm LineEq(Mm A, Mm B) {
    begin_scope
    A.setname("A"); B.setname("B");
    dMm(X);

    #line 1 "d:/MATLAB_C/MATcom/lineeq.m"
    call_stack_begin;
    #line 1 "d:/MATLAB_C/MATcom/lineeq.m"
    // nargin, nargout entry code
    double old_nargin=nargin_val; if(!nargin_set) nargin_val=2.0;
    nargin_set=0;
    double old_nargout=nargout_val; if(!nargout_set) nargout_val=1.0;
    nargout_set=0;

    // translated code

    #line 2 "d:/MATLAB_C/MATcom/lineeq.m"
_   X = mldivide(A,B);
    call_stack_end;

    // nargin, nargout exit code
    nargin_val=old_nargin; nargout_val=old_nargout;

    // function exit code
    A.setname(NULL); B.setname(NULL);
    return X;
    end_scope
  }
/////////////////////////////////////// 结束///////////////////////////////

(4)在VC工程“Test1”中调用转换后函数“LineEq”;

m文件经转换后所得的*.h和*.cpp文件,与一般的C语言编写的程序文件一样,可在各种VisualC++工程中调用。“Test1”工程调用“LineEq”程序清单如下。

code.vc
////////////////////////////////////////////////////////////////// 头文件
#include "stdafx.h"
#include "stdio.h"
#include "matlib.h" /////包含MATcom4.5数学库
#include "LineEq.h"
int main(int argc, char* argv[])
{
//////////////////////////解线性方程组:
 initM(MATCOM_VERSION); ///初始化matlib库
 Mm a,b,x; ////使用矩阵类Mm构造矩阵a,b,x.
 a = (BR(1),2,3,semi,4,5,6,semi,7,8,1);
////////给矩阵a赋值,BR是MATrix<LIB>库的一个宏,用于定义一个矩阵的开始;
////////semi是matrix<Lib>库中的一个常量,作用与“;”相当。
 b = zeros(3,1); ///初始化矩阵b为零矩阵3行1列
 b(1,1) = 37; b(2,1) = 85; b(3,1) = 69; ///给矩阵b赋值
 x = LineEq(a,b); ///调用转化的函数,求解线性方程组的解
 for(int i = 1; i <= x.rows(); i++) ///把解矩阵X的元素显示出来
 {
 for(int j=1;j<=x.cols();j++)
 printf("x(%d,%d)=%f\n",i,j,x.r(i,j));
 }
 exitM(); ///结束对matlib库的调用
return 0;
}
///////////////////////////////////////////////////////结束////////////////////////////////////////

从程序清单中可知,对“LineEq”调用步骤为:

•头文件中需包含"matlib.h"文件,以提供MATcom4.5数学库;

•初始化MATrix<Lib>:

初始化函数为:initM(MATCOM_VERSION);

该函数可多次调用,参数MATCOM_VERSION是一个在matlib.h中定义了的常量,它保证了动态链接库与matlib.h相匹配;

•转换函数调用:M文件经转换后生成的函数,其参数和返回值均为MATcom中的Mm数据类型。因此,转换函数的调用,其语法格式虽与一般C程序调用相同,但对函数参数及返回值的赋值、存取等操作中,应注意Mm数据类型的操作方法,Mm对象操作见1.3.4见。

•结束MATrix<Lib>类库:

结束函数为:exitM();

Test1工程的编译、链接与一般C++程序一样。编译链接成功后,得独立应用程序“Test1.exe”,执行程序后,得线性方程组的解为:

x(1,1) = 3.000000

x(2,1) = 1.000000

x(3,1) = 8.000000