2024年3月19日发(作者:)
维普资讯
总第227期
2008年第9期
计算机与数字工程
Computer&Digital Engineering
Vo1.36 No.9
174
VC6.0与MATLAB 7.X混合编程方法研究
彭博栋
(西北核技术研究所
魏福利
西安710024)
摘要VC++与MATLAB混合编程,可以将VC优秀的可视化编程能力和MATLAB强大的计算能力结合起来。
分析了C语言与MATLAB7.X在接口的特点,详细介绍了VC++6.0与MATI AB7.X混合编程的三种方法:MATI AB
引擎、MATLAB编译器和MATI AB COM编译器。比较分析了各种方法的适用范围,介绍了发布混编程序的方法。
关键词 MATLAB VC++ 混合编程
中图分类号TP311
Research on the Combination Programming for
MATLAB7.X and VC++6.O
Peng Bodong Wei Fuli
(Northwest Institute of Nuclear Technology,Xi’an 710024)
Abstract With the combination of VC++and MATLAB.the power of VC++jn interface programming and the
power of MATLAB in computing are well combined.The interface characteristic MATLAB 7.X with C is analyzed.Three
ways of combination programming for MA
MATLAB Compiler and with MA
TLAB 7.X and VC++6.0 are introduced in detail:with MATLAB engine,with
TLAB Builder for COM.The proper context of different ways iS introduced and com.
pared.The ways of releasing the combination program is introduced.
Key words MATLAB,VC++,combination programming
Class Number TP311
1 引言
MATLAB是美国MathWorks公司研制开发
用C++语言开发涉及矩阵操作较多的程序,不但
费时费力、容易出错,而且运行效率也不一定高。
因此,如何利用MATLAB强大的矩阵操作功能,
结合vc的可视化编程优势进行程序开发,一直是
相关科技人员关注的问题l_】叫]。
的软件产品,是当今世界上使用最为广泛的科学计
算软件之一。它具有强大的科学计算与数据可视
化功能,内置丰富的矩阵处理函数,附有多种面向 MathWorks公司于2005年推出的MAT—
LAB7.X系列版本,较MATLAB6.5有较大的改
变。在MATI AB编译器方面l5j,MATI AB7.X
不同领域的工具箱,广泛应用于控制、通信、信号处
理及科学计算领域中。但是对于可视化功能较多
的应用程序,MATLAB显得力不从心。VC++
6.0是微软于1998年推出的基于c/c++语言的
系列版本不再提供图形库和C语言函数库,不再
提供VC下的编程插件。针对这种情况,具体讨论
可视化编程环境。其功能强大,既适用于与底层交
流信息,又有强大的可视化编程功能,执行速度快,
运行稳定,为许多程序员所喜爱。但是,如果纯粹
了在Vc++6.0环境下与MATI AB7.x系列版
本混合编程的三种方法:利用MATI AB引擎、利
用MATI AB编译器将m文件编译为动态链接库
收稿日期:2008年4月29日,修回日期:2008年5月21日
作者简介:彭博栋,研究实习员,研究方向:图像处理、信号分析。魏福利,副研究员,研究方向:{ag- ̄kN
脉冲辐射诊
,
断。
维普资讯
第36卷(2008)第9期 计算机与数字工程
(DI I )、利用MATI AB Builder for COM将ITI函
数编译封装成COM组件。对每种编程方法,通过
举例说明了其具体实现过程和变量传递规则。
2 VC++6.0调用MATI AB混合
编程方法
2.1 使用MATI AB引擎
MATI AB引擎提供了外部语言(C、Fortran)
访问并调用MATI AB的一种方式。借助MAT—
LAB引擎,外部语言可以将MATLAB当作一个
强大的可编程函数库。开发应用系统,程序界面用
C语言开发,数据处理与计算交由MATI AB完
成,从而缩短开发时问。
MATI AB引擎采用客户机/IR务器(Client/
Server)计算方式l_3]。客户机与服务器既可以存在
于同一台计算机上,也可以分布在两台计算机上,
通过网络来共享信息。在C与MATLAB混合编
程的应用程序中,c/c++程序作为前端客户机,
它向MATI AB引擎传递命令和数据,并从MAT—
LAB引擎接收数据;MATI AB引擎为服务器,在
后台作数据处理。早期的MATLAB引擎采用过
动态数据交换(DDE)技术和ActiveX技术与外部
程序通信,MATI AB6.5及以后版本则采用COM
技术[引。
MATLAB中供C语言调用MATI AB引擎
的函数主要有:engOpen、engClose负责打开和关
闭引擎,engGetVariable、engPutVariable负责从引
擎得到和发送一个MATI AB数组,engEvalString
使引擎执行按照MATLAB语法书写的指令。
通过一个例子,介绍如何在VC下调用MAT—
LAB引擎。首先需要对编译环境进行相应的设
置。假设MATLAB7.X安装在C:\Programe
Files\MATLAB71目录下。首先,打开要调用
MATI AB引擎的VC项目,并在该项目中:
1)在VC菜单中选择:Tools一>Options,选
中Directories,加入以下路径:
Include Files:C\Programe Files\MATLAB71\extern\
include
Library Files:C:\Programe Files\MATLAB71\extern
\lib\win32\microsoft\msvc60
2)在VC菜单中选择:Project-- ̄Settings,选
择Link选项卡,在Category中选择Genernal,在
Object/library moudles项目加入libeng.1ib lib—
mx.1ib libmat.1ib三项,中间空格隔开,确定退出。
Libeng.1ib封装了引擎操作函数,而libmx.1ib和
libmat.1ib封装了有关矩阵操作函数。
3)在项目头文件中包含engine.h
#include”engine.h”
并声明一个Engine类型的指针变量:
Engine ep;
在项目初始化函数中将其置为空:
ep—NULL;
4)下面是在VC6.0中调用MATLAB7.X引
擎的一段代码,示范打开引擎,向引擎传递数组,并
且从引擎返回数据的过程。
//MATLAB引擎与C语言采用mxArray结构进行
数据交换
//声明两个mxArray类型的变量,用于MATLAB与
C语言的数据交换
//操作mxArray变量的函数以mx开头,封装在1m—
mx.1ib由
mxArray T—NULL。*result=NUI I :
double time[5]一(0.0,0.5,1.0,1.5,2.0);
//开启MATLAB引擎,eng一开头的函数均为引擎操
作函数,封装在libeng.1ib中
if(ep一一NULL){
if(!(ep=engOpen(”\O”)))(
AfxMessageBox(T(”Failed to Start MATLAB
Engine!”));
return ̄))
//g,J建实数数组T
T—mxCreateDoubleMatrix(1,5,mxREAL);
//将time值赋予T
memcpy((void*)mxGetPr(T),(void*)time,sizeof
(time));
//将T变量放入MATLAB工作区
engPutVariable(ep,”T”,T);
//本例计算一个自由下落的物体,在T定义的不同时
刻距离落点的位移
engEvalString(ep,”D=0.5*(一9.8)* r. 2”);
//显示计算结果
engEvalString(ep,”plot(T,D);”);
//取计算结果入C工作区,返回类型为mxArray
result=engGetVariable(ep,”D”);
double*d=mxGetPr(result);
//关闭引擎
engClose(ep);
编译运行程序即可。指针d为存储结果的数
组的头指针,读者可自行编程查看。调用MAT—
LAB引擎的程序必须在安装了VC和MATLAB
的计算机上运行,借助于引擎操作函数,用户可以
维普资讯
彭博栋等:C6.0与MATLAB 7.X混合编程方法研究 第36卷
像在MATI AB命令窗口中一样在VC环境下编
写MATI AB程序,操作简单、易于掌握,几乎所有
命令都可以由VC传递给MATI AB运行。在科
学工程应用中,使用MATIAB引擎,也是一种很
好的选择。
2.2 利用MATI AB编译器生成DI I
如果希望编译后的程序可以在没有安装
MATI AB的计算机上运行,则可以利用MAT—
IAB编译器将m文件编译为动态链接库(DLL),
然后在VC中调用。在MATI AB7.X版本中,编
译器版本为4.X。同以前版本相比,MATI AB编
译器4.X不再编译所有的m函数,而只产生必要
的接口函数,供其他程序调用。而那些未被编译的
函数,则被加密后加入组件技术文件(Component
Technology File,CTF)。MATLAB编译器也不
再提供数学库和图形库,而代之以组件运行环境
(MATLAB Component Runtime, MCR)Es]。
MCR是一组标准动态链接库,提供运行程序所需
的基本环境。要在其他计算机上运行程序,必须安
装MCR。
通过一个例子,简单介绍将m文件编译为
DI I 后在VC+4-6.0中的调用方法。
1)在VC中新建基于对话框的项目DI I Dig,
接受所有默认设置。
2)设置MATI AB编译环境。在MATLAB
命令窗口敲入:mbuild—setup,回车。MATI AB
会自动检测安装在本地计算机上的C++编译器,
按照提示选择VC4-4-相应版本即可。此命令只
需运行一次,再次使用MATI AB编译器时,不用
重复设置。
3)新建m文件,写入如下代码:
function z=myMath(x,y)
z一 2+y. 2:
保存,接受MATI AB给出的默认文件名
myMath.m,关闭。该函数将输入的两个向量平方
相加,返回结果存在变量z中。
4)在命令窗口敲入:
mcc—W cpplib:libmyMath--T link:lib myMath.m
回车运行。此命令利用MATI AB编译器将
myMath.m文件编译为C++语言动态链接库。
mcc命令启动MATI AB编译器,一W和~T为控
制选项,后接适肖的参数。一W控制产生的代码
语言类型,cpplib选项使编译器产生C++语言下
的接口函数文件,后接字符串定义了产生的系列文
件的基本名字均为libmyMath。一T指定输出类
型,link:lib代表将代码编译链接成动态链接库。
myMath.m为被编译的m函数,还可以将多个m
文件编入同一个DI L中,只要将文件名列在其后
即可。命令运行成功后,将生成的libmyMath.h、
libmyMath.1ib、libmyMath.ctf、libmyMath.dll拷
贝入项目DI I Dig文件夹下。
5)打开项目DLI Dlg,其路径设置与调用
MATI AB引擎时相同。另外,选择菜单Project一
 ̄Settings项目,在弹出的选项卡中选择Link项,
在Category中选择General,在Object/library
modules中加入libmyMath.1ib mclmcrrt.1ib两
项,中问用空格隔开,确定退出。
6)在DLLDlg.cpp中包含libmyMath.h文
件。在CDLLDlg::OnIn alDialog()中初始化
MCR和库函数:
if(!mcllnitializeApplication(NULL,O)){
AfxMessageBox(
T(”Could not initialize the appli—
cation.”));
return TRUE:}
libmyMathlnitialize();
7)在CDI LDlg::OnOK()中声明初始化变
量,然后传递给DI L中的函数,最后取回变量:
mwArray mwz(1,5,mxDOUBI E
CLASS,mxRE—
AL):
mwArray mWX(1,5,mxIX)UBLE
—
CI ASS,mxRE—
AL):
mwArray mwy(1,5,mxEXOUBI E
CLASS,mxRE—
—
AL):
double xES2一{1,2,3,4,5);
double yEs]一{7,8,9,11,15);
//将数组x、Y中的数据放入mwx和mwy中
mwx,SetData(X,5);
mwy.SetData(y,5);
//调用DLL中的函数,mwx,mwy为输入参数,输
出结果保存在mwz中
myMath(1,mwz,mwx,mwy);
//将结果mww中的数据放人数组Z中
double zE5];
mwz.GetData(z,5):
//结束库函数和MCR环境
libmyMathTerminate();
mclTerminateApplication();
mwArray是MATI AB为C++语言接口封
装的类,支持MATLAB内的各种变量。观察l|b—
myMath.h文件内容,可见myMath函数原型为
维普资讯
第36卷(2008)第9期 计算机与数字工程
void myadd(int nargout,mwArray&z,const
LAB71\,保存退出即可。
mwArray ̄X,const mwArray&y),其调用规则
为第一个参数为输出变量个数,对于myMath函数
为1,随后紧跟的是一系列输出变量,输出变量结
束后为一系列输入变量,输入输出变量都为
在VC++环境下调用COM比较复杂。通过
例子,具体说明在MATI AB下生成COM组件并
在VC++6.0中调用的方法和参数传递规则。
1)在MATLAB命令窗口,利用mbuild--set—
mwArray类型。
8)编译链接项目,运行即可。
要使编译后的DI L文件能够发布到没有安装
MATI AB的计算机上,必须在目标计算机上安装
MCR。利用MATI AB命令buildmcr创建可以发
布的MCR安装文件MCRInstaller。需要发布的
文件应该包括:编译得到的可执行文件;CTF文
件;MCRInstaller.zip。在最终的用户计算机上,将
MCRInstaller.zip解压,安装MCR,就可以使用编
译后的程序了。
2.3 利用MATI AB COM编译器产生C()M组件
组件对象模型(COM,Component Object
Mode1)是Microsoft提出的以组件为发布单元的
软件开发技术,该技术使得在不同平台上用不同语
言开发的代码能够协同工作。COM所具有的语
言、平台无关的特性,方便了软件的升级、定制与替
换,是理想的软件应用方案。简言之,COM是一种
Client/Server标准,提供了一类应用程序接口,允
许任何符合标准的程序访问l4]。
Matlab CoM Builder 1.0于2002年6月在
Matlab6.5版中推出,在MATI AB7.X中更名为
MATI AB Builder for C0M,版本为1.1。其工作
原理为利用MATIAB的编译器把MATLAB程
序转换成c/c++源程序,然后再调用外部C++
编译器来编译、生成COM对象l5]。
需要指出的是,如果MATLAB安装路径内有
空格,如:C:\Programe Files\MATLAB71,则
MATI AB COM编译器在使用VC++6.0编译
器进行编译时会报错终止。在MATI AB6.5版本
下则没有此问题。解决办法一是将MATLAB安
装在根目录下,二是改变compopts.bat文件的内
容。介绍一下后一种方法。假设MATLAB安装
在C:\Programe Files\MATLAB71目录下,在
MATLAB命令窗口下敲人:
cd(prefdir);
copyfile( compopts.bat", compopts—old.bat');
edit( compopts.bat');
在打开的comopts.bat文件中,将其第66行
的 MATI AB 替换为C:\Progra~1\MAT—
up设置编译环境,如果已经设置过,则跳过此步。
2)新建一个m文件,写入如下内容:
function y=myMagic(size)
y=magic(size);
保存关闭,该函数输出一个魔方数组,数组维
数由输人参数size指定。
3)在MATI AB命令窗口敲人:comtool回车,
启动MATLAB Builder for C0M。选择File~>
New Project,弹出新建项目设置对话框,在Corn—
ponent Name内填人Corn—Magic,在下面的Class
name内输入Class—Magic,选择右侧Classes内自
动生成的Corn—Magicclass,点击remove按钮,将
其删除。点击确定按钮,项目设置完成。
4)选择Project-->Add File…,将刚才保存的
myMagic.m文件加入项目。还可以陆续加入其它
文件,本例只加入一个文件即可。选择菜单Build,
选择COM Object,等待过程结束。由提示可以看
出,该过程自动生成COM组件及相关文件,并且
在系统中注册组件。
5)在VC++中新建一个基于对话框的项目,
名字为ComDlg,接受其他所有默认设置。
6)将第4步生成的Corn—Magic—id1.h、Corn—
Magic
—
idlj.C、mwcomtypes.h拷贝入项目文件
夹,并且将前两个文件加入ComDlg.cpp中:
#include”Corn Magicid1.h”
#include”Corn
_
M ̄i%idLi.C”
7)在CComDlg::OnOK()中初始化COM应
用环境,声明VARIANT变量,并传递给COM接
口,然后取回输出结果到VC++中:
//初始化COM应用环境
::
Colnitialize(NULL);
//调用系统函数,得到组件CLSID
HRESULT hr;CLSID clsid;
hr一::CLSIDFromProglD(OLESTR(”Com
Magic.
—
Class
Magic.1
0”),&clsid);
—_
//由CLS1D获得IClass—Magic的接口
IClass Magic pMagicClass;
hr=::CoCreateInstance(clsid,NULL,CLSCTX
—
IN—
PROC SERVER,uuidof(IClass
—
Magic),(LPVO1D*)
 ̄pMagicClass);
维普资讯
178 彭博栋等:C6.0与MATLAB 7.x混合编程方法研究 第36卷
//声明COM组件接口函数所需的VARIANT类型的
输入输出变量
VARIANT out,size;::VariantInit(&out);::Varian
tInit(&size):
//VARIANT变量的类型声明和赋值
size.vt=VT I4;size.IVal=3;
//输出为数组类型
out.vt=VT
R8 l Vrr_ARRAY;
SAFEARRAYB()uND bound[1];
bound[0].cElements=size.IVal*size.1val;
bound[0].ILbound=0;
out.parray一 SafeArrayCreate(VT
R8,1,bound);
//* ̄l用所得到的IClassMagic接口,调用函数
myMagic
//其函数调用规则与MATI AB生成的DLL语言相
似
pMagicClass-- ̄myMagic(1, out,size);
//输出结果位于out数组中,把数据复制到nREs指针
所指向的内存中
double*nRes;
double HUGEP pDest;
nRes=new double[size.IVal*size.IVa1]:
::memset(nRes,0,size.1Val size.IVal sizeof(doub
le));
::
SafeArra【yAccessData(out.parray,(void HUGEP*
*) ̄>pDest);
::memcpy(nRes,pDest,size.IVal size.IVal*sizeof
(double));
//清除变量
::
VariantClear(&out);::VariantClear(&size);::
SafeArrayDestroy(out.parry);
::
CoUninitialize();
8)编译运行程序。
上述由组件CI SID获得组件接口过程中,限
于篇幅,省去了错误检查相关代码。VARIANT是
一
个结构,HJ于与COM组件传递参数,可以代表
任何数据类型,可以通过此结构的不同域设置变量
类型和变量值。SafeArray系列系统函数可以保证
在不同进程、不同机器、不同操作系统下安全的访
问数组。上述操作已经带有了一点COM的味道。
要在没有安装MATLAB的计算机上运行调用了
MATLAB组件的程序,需满足两个条件:一是目
标计算机上安装了MCR,二是组件在目标计算机
上已经注册。具体做法是,利用MATI AB CCIM
编译器打开需要打包的项目,选择Component--
Package component命令,会将发布该组件所需的
所有文件打包到一个和项目同名的可执行文件中,
在打包组件的时候要选择包含MCR。打包产生的
可执行文件会在目标计算机上安装MCR并且在
系统中注册组件。
MATLAB C0M编译器给用户提供了另外一
种代码重用以及程序发布的方式,使得MATLAB
应用程序更加容易发布和配置。虽然在VC中操
作COM组件显得有些繁琐,但是编程期间不需要
对VC的编译环境做多余的配置。作为Math—
Works公司力推的混合编程工具,MATI AB COM
编译器会进一步完善,这种新的混编技术无疑将是
今后混合编程的发展方向。
3 结语
熟悉和掌握了在VC++环境下调用MAT—
LAB外部接口的方法,可以充分结合VC++的可
视化编程能力和MATI AB的数据处理功能,将科
技人员从繁杂的编程中解放出来,将注意力更多的
集中在算法的优化和提高上,提高开发效率。
参考文献
[1]伍华健.MATLAB/VC++组合编程方法及其应
用[J].微计算机信息,2007,23:219 ̄220
[23牟或清,王汝霖,李国新.MATI AB与VC接口技
术的研究[J].微机算机信息,2006,22:275 ̄277
I-3]李天昀,葛临东.综述MATLAB与VC++的交互
编程[J].计算机仿真,2004,(9):193~196
[4]王晓春,曹鸣,罗永新.基于COM的VC与Matlab
的混合编程技术[J].现代电子技术,2004,19:16~23
I-s]董维国.深入浅出MATLAB 7.X混合编程[M2.北
京:机械工业出版社,2006,(1):193


发布评论