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