摘 要:本文从不同的角度论述了Visual C++6.0与工程计算语言MATLAB的混合编程。通过二者的结合,既有效的利用Matlab众多的函数,大大减少程序设计的工作量,又继承了VC良好的程序界面,因此不失为一种很好的程序设计方法。
关键词:Matlab,混合编程,MATCOM
一、引言
在科学研究和工程应用中,MATLAB的应用已经比较普遍,它强大的计算、绘图、仿真功能为众多工程人员所喜爱,但在MATLAB环境下编成的M文件运行较慢,所以必须采用与C/FORTRAN混合编程的方式来提高程序的运行速度。MATLAB与VC的混合编程大致可以分为两类:一类需要MATLAB后台支持的混合编程,一类是不需要MATLAB支持而生成独立运行程序的混合编程。下面分别阐述:
二、需要MATLAB后台支持的混合编程
这种编程方法大体又可以分为两类:
(一)将原有的c程序写成子函数的形式,然后在其中加入固定格式的void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])函数,然后调用MATLAB的mex指令,在mex后输入要编译的c程序名,即可生成可在MATLAB环境下直接运行的dll文件。关于这方面的知识在很多文章及MATLAB的PDF帮助文档中已有很详细的阐述,这里不在详细论述。
(二)通过外部调用的方法实现
首先将m文件的文件名加入到一段C程序中,通过MATLAB中的mex批处理文件将该C文 件生成exe文件,然后通过VC的外部调用的函数:shellexec()或winexec()实现调用。
mex批处理文件的调用格式如下:
mex -f msvc60engmatopts.bat *.c
直接用MATLAB5.3提供的msvc60engmatopts.bat时,编译出现Could not find the compiler "cl" on the DOS path.错误。作者对msvc60engmatopts.bat加以修改,编译通过。修改如下:
set MATLAB=%MATLAB%
//VC的安装目录,视其安装路径而定
set MSVC_ROOT=c:\microsoft visual studio
set MSVCDir=%MSVC_ROOT%\VC98
set MSDevDir=%MSVC_ROOT%\Common\msdev98
c文件的格式如下:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <engine.h>
void main()
{
Engine *ep;
/*
* Start the MATLAB engine
*/
if (!(ep = engOpen(NULL))) {
MessageBox ((HWND)NULL, (LPSTR)"Can't start MATLAB engine", (LPSTR)
"sample1.c",MB_OK);
exit(-1);
}
engEvalString(ep, "contour(peaks)");
}
程序中的黑色字体部分可以加入MATLAB的函数,也可以加入事先编好的m文件的文件名。比如有一个文件为myprogram.m,则应写成engEvalString(ep, "myprogram")。程序运行时界面如图一所示。
图一: 程序运行时界面(等高线)
通过MATLAB的MEX指令编译这一c程序就生成了与c文件同名的exe文件,通过VC中的外部调用函数便很容易的实现了对MATLAB的调用。其调用格式如下:
WinExec("*.exe", NULL)//注意输入正确的应用程序所在的路径,具体可参见VC的帮助。运行此方法生成的EXE文件,必须依靠MATLAB作为后台运行环境。
三、利用MIDEVA生成不需要MATLAB后台支持的程序
上述方法虽然实现了VC与MATLAB的混合编程,但仍然需要MATLAB这一庞大的运行环境。而MIDEVA在这方面则体现了它的巨大的优越性。MIDEVA是mathtools公司推出的一个MATLAB环境的替代产品,是一个建立在编译基础上的M语言的集成开发环境,集编辑、调试、编译和优化于一体,是该公司原来的MATCOM的扩张。在很多方面MIDEVA比MATLAB强大,它最主要特点是能够将M语言的文件转化为C语言的代码,并通过Visual C++和Borland C++将其编译成可执行程序(exe)或动态链接库(dll)。这个特点也是mathtools之所以要推出该软件的出发点。众所周知,高级计算机语言可分为解释执行和编译执行两大类,后者一次性将源代码转化为机器代码,而解释执行则一般是在源代码基础上解释一句执行一句,所以后者比前者的运行速度快的多。MATLAB环境中M语言是解释执行的,因而虽然在算法的形成阶段调试和修改都很简单快捷,但当算法成熟了要推出新编的软件作为成品的时候却有许多困难。首先是运行速度很慢,和C、FORTRAN等算法语言的程序不在一个数量级上,其次是只能用源码的方式发行,知识产权得不到保障。这样MIDEVA就有了它的用武之地,通过编译成C代码就使用户可以方便地将M语言和C语言综合在一起,而不用在一大堆dll文件中调来调去,利用强大的VC、BC的编译器可以形成最紧凑高效的本机代码。 下面讲一下MIDEVA的几种关键用法
(一)利用MATCOM生成独立执行的EXE文件
虽然在MATLAB环境中也可以由M文件生成执行程序,但此EXE文件仍不能脱离MATLAB的后台支持,利用MATCOM则可以生成不再需要MATLAB环境支持的EXE文件。其生成方法相当简便,直接利用MATCOM菜单File /Compile to exe/,然后选择你要生成的M文件,MATCOM便会自动完成EXE文件的编译与链接。编译完以后,你便可以在DEBUG目录中找到与M文件同名的EXE文件。
(二)利用MATCOM生成动态连接库(dll)文件
这一功能只针对VC而开发,dll的生成方法如同生成EXE文件的方法,它可以生成针对VB,EXCEL,DEPHI等的动态连接库文件,使用起来非常方便。生成dll的过程中同样要生成CPP文件,mathtools公司建议用户:如果是用VC开发程序的话,最好直接使用MATCOM编译生成的CPP文件,而不是直接使用dll文件。
(三)实现在Visual C++6.0环境中直接对M文件进行编译
进入VC++6.0后,点击Tools菜单,然后点Customize,选择Add-ins and macro files,点击Browse,然后选择插入的文件类型为.dll文件,在MATCOM的bin目录下找到mvcide.dll,点击OK. 在VC的工具栏中便会出现一个新的工具栏,这样就可以直接在VC环境下编译M文件了,如同编译c程序一样简单。加入工具栏后VC变为如图二所示的界面:
图二:VisualC++6.0加入一新工具栏
Example:
1. VC下创建一Win32 Console Application.
2. 点击工具栏中的m++工具,选择你的m文件,点击OK.
3. 编译,运行即可.
(四)利用Virsual matrixLIB在MFC中编程
利用Virsual matrixLIB可以把科学计算及图形显示集成到MFC中,实现M程序与MFC的强强结合。
Example:
1. 在VC下创建MFC AppWinzard(EXE),假设创建程序名为mfc,第一步选择Multiple documents.
2. 点击Project / Add to Project / Files,加入MATCOM的lib目录下的库文件v4500v.lib.
3. 将要实现的程序段加入到CmfcView::OnDraw()函数中,当然也可以加入自己定义的函数中,但程序必须遵循MATCOM的语法。
下面的程序实现了同MATLAB中contour(peaks)相同的功能:
//Mm 定义变量
//CL是一个关键字,是多变量输入时所必须使用的,用以指明调用的变量;TM指明这//是一个字符。
#include "matlib.h" //必须包含此头文件
void CmfcView::OnDraw(CDC* pDC)
{
CXxDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!init) {
initM(MATCOM_VERSION);//初始化
Mm h = winaxes(m_hWnd);
axesposition(0,0,400,200);//窗口位置
Mm a;//定义变量
a=peaks();
contour(CL(a)); //相当于MATLAB中的contour(peaks)
title((CL(TM("contour plot")))); //标题
xlabel((CL(TM("This is the x axis"))));
ylabel((CL(TM("This is the y axis"))));
set(h,(CL(TM("Color")),TM("white")));//背景色
set(h,(CL(TM("Box")),TM("on")));
init=true; }
drawnow();
}
程序运行时界面如图三所示。
本文所有程序均在Visual C++ 6。0及MATLAB5.3环境下编译通过。
四、结论
MATCOM将M文件转换为CPP文件,既保持了MATLAB的优良算法,又保持了C++的高执行效率,而且生成的执行程序脱离了MATLAB的开发环境,更有利于软件的开发与发布。因此不失为一种很好的程序设计方法。
图三: 程序运行时的界面(等高线)
|