明辉手游网中心:是一个免费提供流行视频软件教程、在线学习分享的学习平台!

Matlab与VC集成

[摘要]◆ 上海大学通信与信息工程学院 杨高波 Matlab是一个具有强大的矩阵运算、数据处理和图形显示功能的软件,其输出结果可视化,编程效率极高,极少的代码即可实现复杂的运行,然而其边解释边执行,运算效率...
◆ 上海大学通信与信息工程学院 杨高波

Matlab是一个具有强大的矩阵运算、数据处理和图形显示功能的软件,其输出结果可视化,编程效率极高,极少的代码即可实现复杂的运行,然而其边解释边执行,运算效率较低,实现相同功能的代码跟其他编程平台相比运行时间相对较长,且不适合作为通用的编程平台。因此,许多Matlab的应用程序需要使用诸如VC之类的通用编程平台,实现Matlab与VC的混合编程,这样有助于发挥Matlab和VC的各自优势。

集成的几种实现方法

为了实现混合编程,Matlab 5.0以后版本自带了C语言编译器(Compiler), 可以将M文件转换为C-MEX或C/C++程序。根据Matlab是否运行,一般将Matlab与VC混合编程分为两大类:Matlab在后台运行和可以脱离Matlab环境运行。

1.Matlab引擎(Engine)采用客户机/服务器(Client/Server)的计算方式,通过Windows的ActivcX通道和Matlab接口。在具体的应用中,VC的程序作为前端客户机,通过调用Matlab Engine在后台与Matlab服务器建立连接,实现动态通信。这种方法实现较为简单,不要求连接整个Matlab,只需要嵌入必要的Matlab Engine库,可大大地节省系统资源,但这种Matlab在后台运行,运行效率低下。

2.Mideva是Mathtools公司推出的一种Matlab集成编译开发平台,提供对Matlab程序文件(M文件)的解释执行和开发环境支持。经过简单设置后Mideva可以将M源文件转换为C/C++,然后添加到MSVC、C++ Builder的工程中。

3. 另一种方法是先利用Mideva直接生成EXE文件(方法是启动Mideva,在菜单“File->Compile to exe”中, 选出需要转换的M文件),然后在VC中通过Shell调用,常见的外部函数有shellexec()或winexec()。这种方法简单方便,但运行时出现一个控制台窗口,而且由于VC和Matlab之间不能交互,通用性差,仅适用于VC中调用Matlab实现图形显示的场合。

4. 最新也是最方便的方法是通过Matlab 6.0 Add-in实现Matlab与VC的混合编程。

以上方法1需要Matlab在后台运行,方法2、3、4可以脱离Matlab环境运行。

Matlab Add-in

Matlab 6.0以后版本对其Compiler作了较大的改进,其支持更多的数据类型,更强的优化功能,更为重要的是其Matlab Add-in提供了一个Matlab和VC直接集成的途径。它具有一些新的特征:快速集成M文件到C++工程中,创建独立的 C/C++应用程序或C MEX DLL;通过M文件创建共享库或MEX文件;内含Visual Matrix Viewer,调试过程中可以查看矩阵变量的值; 直接修改M源文件而不是修改生成的C/C++文件;方便快捷地打包应用程序等。

Matlab Add-in的安装:

1. 启动Matlab,运行“mex-setup”,按照菜单提示选取MSVC。它将配置MEX使用MSVC为默认的编译器(创建C-MEX文件必需),并安装Matlab Add-in所需文件到MSVC目录。

2. 在Matlab环境下运行“mbuild-setup”, 按提示选取MSVC。它将配置使用MSVC为默认的编译器(创建独立应用程序必需),并安装Matlab Add-in所需的Matlab Compiler和C/C++数学库文件到MSVC目录。

3. 在Matlab环境下运行“cd(prefdir)”和“mccsavepath”。它将保存当前Matlab路径到mccpath文件中,这是因为Matlab Add-in脱离Matlab运行,否则它无从知道Matlab路径。

4. 在MSVC环境中配置Matlab Add-in,方法是:从菜单“Tools -> Customize”选择“Add-ins and Macro Files”选项卡,选中“Matlab Add-in”, 点击“Close”。MSVC工具栏出现Matlab Add-in图标,以后每次启动VC,自动加载Matlab Add-in。

5. 配置Windows系统。在Windows 95/98系统下,找到config.sys, 添加一行:shell= c:\ command.com /e:32768 /p(Windows ME有所不同,需设置Conagent.exe的属性Memory选项卡的Initial Environment值为4096)。从表面看,VC的环境设置也是步骤较多,但只需设置一次。

程序示例

下面以创建一个Standalone程序为例具体说明。启动MSVC,打开“File->New”菜单,选择Project,选择“Matlab Project Wizard”, Project Name命名为Mytest, 点击Next,你可以选择所生成的应用程序的类型:Windows Console EXE、C-MEX DLL、M-MEX DLL、Shared M-DLL; C程序还是C++程序;选取Debug、Release模式;选择是否生成Main函数;是否需要支持图形。这里选择生成C++程序,其余采取默认设置,点击“Finish”,出现对话框要求选择添加到工程中的M源文件,选择文件testplot.m后,这时你可以看到MSVC调用MCC生成一个混合M文件和C的工程。在“File View”选项卡中可以看到添加的M文件和自动生成的C++文件。

这时大功告成,即可按F7编译后按F5运行了,运行结果如下图所示。



程序运行结果

这里用到的testplot.m内容如下(先在Matlab里编辑好):

function mytest()

t=0: 0.05*pi: 2*pi;

y=sin(t);

plot(t,y,‘b*’);

可以通过双击Matlab M-files文件夹下testplot.m打开观察。生成的testplot.cpp代码如下(略有删节):

// MATLAB Compiler: 2.1 Date: Sat Nov 03 16:37:08 2001

#include “testplot.hpp”

#include “libmatlbm.hpp”

static double _array0_[41] = { 0.0,.157,....};

//自动生成的数组

void InitializeModule_testplot() {

}

void TerminateModule_testplot() {

}

static void Mtestplot();

_mexLocalFunctionTable _local_function_

table_testplot = { 0, (mexFunctionTableEntry *)NULL };

void mlxTestplot(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]) {

MW_BEGIN_MLX();

{

if (nlhs > 0) {

error(mwArray(“Run-time Error: File: testplot Line: 1 Column: 1 The function \‘testplot\’was called with more than the declared number of outputs (0). ”));

}

if (nrhs > 0) {

error(mwArray(“Run-time Error: File: testplot Line: 1 Column: 1 The function \‘testplot\’ was called with more than the declared number of inputs (0).”));

}

Mtestplot();

}

MW_END_MLX();

}

#line 1 “D:\\ygbtest\\testplot.m”

static void Mtestplot() {

#line 1 “D:\\ygbtest\\testplot.m”

mclMlineEnterFunction(“D:\\ygbtest\\testplot

.m”, “testplot”)

#line 1 “D:\\ygbtest\\testplot.m”

mwLocalFunctionTable save_local_

function_table_(&_local_function_table_testplot);

#line 1 “D:\\ygbtest\\testplot.m”

mwArray ans(mclGetUninitializedArray());

#line 1 “D:\\ygbtest\\testplot.m”

mwArray y(mclGetUninitializedArray());

#line 1 “D:\\ygbtest\\testplot.m”

mwArray t(mclGetUninitializedArray());

// t=0: 0.05*pi: 2*pi;

//

#line 2 “D:\\ygbtest\\testplot.m”

mclMline(2);

#line 2 “D:\\ygbtest\\testplot.m”

t = mwArray(1, 41, _array0_, (double *)NULL);

//

// y=sin(t);

//

#line 3 “D:\\ygbtest\\testplot.m”

mclMline(3);

#line 3 “D:\\ygbtest\\testplot.m”

y = sin(mwVv(t,“t”));

//

// plot(t,y,‘b*’);

//

#line 4 “D:\\ygbtest\\testplot.m”

mclMline(4);

#line 4 “D:\\ygbtest\\testplot.m”

ans.EqAns(Nplot(0, mwVarargin(mwVv(t, “t”), mwVv(y, “y”), “b*”)));

#line 4 “D:\\ygbtest\\testplot.m”

mclMlineExitFunction();

#line 4 “D:\\ygbtest\\testplot.m”

}

自动生成的testplot_mainhg.cpp代码如下:

#include “matlab.hpp”

//加入Matlab头文件

#include “libsglinit.hpp”

#include “testplot.hpp”

//加入应用程序头文件

static mexFunctionTableEntry function_table[1] = { { “testplot”, mlxTestplot, 0, 0, &_local_function_table_testplot } };

static _mexcppInitTermTableEntry init_term_table[1] = { { InitializeModule_testplot, TerminateModule_testplot } };

static _mexcpp_information _main_info = { 1, 1, function_table, 0, NULL, 0, NULL, 1, init_term_table };

可以看到没有添加一句C/C++代码,即生成了一个Matlab的Standalone应用程序(是不是太容易啦)。需要注意两点: 一是添加到MSVC工程的文件应当为一个函数文件,而不能是一个Script文件,否则会出现错误提示; 二是最好不要修改生成的C/C++代码,如果需要改动,可以通过在MSVC工作区中直接修改M文件(无须在Matlab环境中),重新编译即可。你可以通过在M文件中设置断点,在运行中通过Matrix Viewer观察Matlab变量的值。

目前通过Add-in实现Matlab与VC的混合编程也有一定的不足:如目前并不支持所有的Matlab的函数;生成的程序代码有些繁杂等。估计Matlab 6.0以后的版本在这方面肯定有所改进的。

结 论

Matlab Add-in提供了一种实现Matlab和VC混合编程的直接集成的途径,通过它可以很方便地生成Matlab和VC的混合程序。在图像处理等需要大量计算的工程应用场合有广泛的应用价值。