本节以一个线性方程组的求解过程为例,介绍通过MATcom实现VC对MATLAB m文件的调用。
(1)编写MATLAB m文件“LineEq.m”,用于求解线性方程组的解;
MATLAB m文件清单:
%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完成工程创建工作。
图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进行修改,再重新转化直到没有错误报告为止。
图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类型。
/////////////////////////////////////////// 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调用环境;
pragma hdrstop
"LineEq.h"作用与一般的C++程序相同,是函数定义头文件,为程序提供转换后C++代码中使用的数据类型、函数原型及常量等信息。
///////////////////////////////////////////////////////// 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”程序清单如下。
////////////////////////////////////////////////////////////////// 头文件
#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