Matlab和Visual C++的混合编程

更新时间:2023-07-19 00:31:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Matlab和Visual C++的混合编程

Matlab和Visual C++的混合编程

(信息工程学院,计算机系,计算机科学与技术专业 陈健)

(学号:2000131001)

内容提要:在对如今领导潮流的两个强大的可视化开发工具Microsoft Visual C++和Matlab间的混合编程作了大量的尝试的基础上,本文总结出5种行之有效的应用于数字图像处理软件开发的集成途径;对它们各自的优点和不足作了详细的阐述;并对未来两个软件的进一步联合提出了一些粗浅的意见和希望。

关 键 词:编程,混合编程,Matlab Visual C++

教师点评:Matlab是功能强大的高性能数值计算和可视化软件系统,具有较好的数值分析、信号处理、图形和图像处理等方面的功能。本论文将VC++与Matlab结合起来,实现混合编程,既发挥VC++在图像的各种处理中编程灵活、执行快捷的特点,又发挥Matlab在数值分析、信号处理及图形和图像等方面简单易用的优势,使整个系统既简洁又高效。该论文概念清楚,观点合理,编程工作量较大,是一篇优秀的本科论文。(点评教师:蔡茂国,教授)

一、混合编程的原因与优势

Matlab(Matrix Laboratory,矩阵实验室)是一种高性能的数值计算和可视化软件的开发软件,在数值分析、信号处理、系统辨识、特殊函数和图形等方面具有广泛的应用。由于Matlab用的是一种脚本语言,其执行是逐行解释的,而且为了加强通用性,程序中所有的变量都用矩阵数组MxArray来实现,所以,在实现一些复杂的算法时,程序执行效率低。虽然Mathworks公司已经在竭力提高m脚本文件(script files)的运算速度,但仍然不能和实现同样功能的可执行程序相比,而且m脚本文件不能脱离Matlab环境运行的,也制约了Matlab程序的可移植性和通用性。

C++是新一代面向对象(OOP)高级程序设计语言,由于它建立在C的基础之上,使之成为最流行的OOP语言。Visual C++在功能和优化等方面,是同类产品的佼佼者,并且绝大多数的软件开发包都提供了对它的接口。

虽然Visual C++是目前综合性能最高,功能最强大的可视化开发工具,但其在图像处理方面并没有专门的功能函数库,我们在利用Visual C++编写图像处理的程序时,实现一些基本的图像处理功能如平移、缩放、腐蚀等都要重新架构自己的图像处理函数库,编写大量的代码,开发效率不高;而Matlab虽然有完整的图像处理工具箱,编程效率高,极少的代码即可实现复杂的运行,但由于它是解释型脚本语言,执行效率低,实现相同功能的代码跟其他编程平台相比运行时间相对较长,而且不适合作为通用的编程平台。因此,如果能实现两个开发工具的混合编程,各取所长,充分发挥两个开发工具的优势,将给我们的开发工作带来极大的便利。

二、Visual C++和Matlab混合编程的有效途径

根据Matlab是否运行,一般将Matlab与Visual C++混合编程分为两大类:Matlab在后台运行和可以脱离Matlab环境运行。

2.1 Matlab引擎(Engine)

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

Matlab engine提供了一组 Matlab API 函数,通过这些 API 函数实现应用程序进程之间的传递数据,Matlab engine 库中的API函数如下:

1) engOpen,开启Matlab engine

2) engClose,关闭Matlab engine

Matlab和Visual C++的混合编程

3) engGetArray,从Matlab engine中获得一个Matlab矩阵,用于数据交换

4) engEvalString,执行一个Matlab命令

5) engPutArray,从应用程序向Matlab engine发送一个Matlab矩阵,用于数据交换

6) engOutputBuffer,作用是创建字符缓冲区以获取Matlab文本输出

运用Matlab engine和Visual C++集成开发步骤如下:

1) 导入相应的库。Visual C++要调用Malab engine,就需要相应的库文件,在Matlab安装目录下\extern\include\下有如下文件:libeng.def、libmx.def、libmat.def和matlab.def等,在DOS命令提示符下执行命令生成相应的库文件。生成lib的命令如下:

lib /def:libeng.def /out:libeng.lib /machine:ix86

生成了libeng.lib、libmx.lib、libmat.lib和matlab.lib之后,把它们加入到Visual C++工程的Project->Setting->link->Object/Library Modules文本框中。

2) 编写m文件。根据我们需要的图像处理功能编写m函数或者脚本。

3) Visual C++界面设计。

4) 把m文件加入到Visual C++工程中,在调用engine的文件中加入 #include “engine.h”,在CMainFrame的构造函数中加入如下代码:

Engine *ep;

if( !( ep = engOpen( NULL) ) )

{

fprint( stderr, “\nCan’t start Matlab engine\n”);

return EXIT_FAILURE;

}

在析构函数中加入engClose( ep );,在相应的菜单相应函数中加入类似 engEvalString( ep, “surf( peaks )” );等执行Matlab语句的代码。

以上就运用Matlab engine在Visual C++工程里面执行matlab的语句或者m文件,这一方法不能脱离Matlab的后台运行,要求运行这种程序的用户的计算机都装上一个庞大的Matlab,所以这样的结合方式不能用于商业用途和推广。

2.2 Matlab Add-in

Matlab 6.0以后版本对其Compiler作了较大的改进,改进之一是其Matlab Add-in提供了一个Matlab和Visual C++直接集成的途径。它可以快速集成m文件到C++工程中,创建独立的 C/C++应用程序或C MEX DLL;可以通过m文件创建共享库或MEX文件;可以内含Visual Matrix Viewer,调试过程中可以查看矩阵变量的值;直接修改m源文件而不是修改生成的C/C++文件;可以方便快捷地打包应用程序。

Matlab Add-in的安装:

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

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

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

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

5) 配置Windows系统。在Windows 95/98系统下,找到config.sys,添加一行:shell= c:\ /e:32768 /p(Windows ME有所不同,需设置Conagent.exe的属性Memory选项卡的Initial Environment值为4096)。

通过Matlab Add-in创建一个Stand-alone程序步骤:

1) 启动Visual C++,创建一个“Matlab Project Wizard”Project。

2) 点击Next,你可以选择所生成的应用程序的类型:Windows Console EXE、C-MEX

Matlab和Visual C++的混合编程

DLL、M-MEX DLL、Shared M-DLL等;选择是C程序还是C++程序;选取Debug、Release模式;选择是否生成Main函数;是否需要支持图形。

3) 点击“Finish”,出现对话框要求选择添加到工程中的m源文件,选择所要添加的m文件,这时可看到Visual C++调用MCC生成一个混合m文件和C++文件的工程。在“File View”选项卡中可以看到添加的m文件和自动生成的C++文件。编译之后就可以实现m文件代码的功能。

注意事项:

1) 加到Microsoft Visual C++工程的文件应当为一个m函数文件,而不能是一个Script文件,否则会出现错误提示;

2) 如果需要改动,可以通过在Visual C++工作区中直接修改m文件,重新编译即可。 通过Add-in实现Matlab与Visual C++的混合编程虽然简便快捷,但仍然有一定的不足:如目前并不支持所有的Matlab的函数;生成的程序代码繁杂等。“mbuild -setup”只是将C/C++数学库文件复制到Microsoft Visual C++目录,通过查看一下C/C++数学库,C/C++图形库的帮助说明,可以发现很多图像处理的函数,如imhist函数,edge函数都不在库里,所以很多图像处理的函数并不能通过Add-in的方式,实现Matlab的各种图像处理到Visual C++的移植。

2.3 Matcom

MathTools 公司推出的 Matcom4.5,可以把 Matlab 的m文件转成相同功能的C++代码,将其放置到Visual C++工程的适当位置即可。Matcom编译m文件,先将m文件按照与Matcom的cpp库的对应关系翻译为cpp源代码,然后用对应版本的c编译器将cpp文件编译成相应的exe或dll文件,所以第一次运行要指定c编译器的路径,这一工作在安装Matcom时自动完成,指定好的编译信息写在Matcom\bin\matcom.ini文件中。Matcom4.5版中使用TeeChart3.0 OCX控件,因而它支持图形操作。

运用Matcom集成Matlab和Visual C++的步骤:

1) 运行Mideva在主界面上直接打开m文件,在菜单中选择compile to dll,输入要编译的m文件名,然后在Matcom的debug目录下(这个目录可以自定义)可以找到这样的编译好的.c、.h、.cpp、.lib、.dll、.exp等文件。

2) 将上述的.h和.cpp文件加入工程中,并在相应的文件中加入#include “stdafx.h”。

3) 添加连接库,在Visual C++的Tools\option\directory\下的include选项中加入matcom目录的lib(包含matcom.h)。

4) 添加matcom目录的lib路径中的v4501.lib(根据matcom版本的不同,这个lib的名字也不一样,但是matcom的lib路径中只有一个lib)到Visual C++所建立的工程中。

5) 修改C++源代码:

1、 在头文件处包含matlib.h,即加入#define MLIB 0和#include “matlib.h”;

2、 在类成员函数的InitInstance中调用InitM启动对Matlab函数的调用,可加入如下代码TRACE0( “initM\n” );initM( stin, stout, sterr );;

3、 在类析构函数中调用exitM()结束对Matlab函数的调用;

4、 在程序中合适的位置插入经Matcom翻译过后的C++源码,但要注意在类构造函数中不要调用任何Matlab函数;

5、 编译运行程序。

利用Matcom可方便地对m文件转换,生成的代码可读性很好,而且转换同时可生成可供Visual C++调用的动态连接库,其使用和一般的动态库一样。再者Matcom不仅可转换独立的不依赖于其它m文件的m文件,亦可转换调用其它m文件的m文件嵌套,条件是所调用的m文件在同一个目录下面。

利用Matcom存在的问题跟利用Matlab Add-in存在的问题一样,这种转换方法只支持C/C++数学库,C/C++图形库中所提供的函数,超出此范围的Matlab图像处理函数目前还没有办法成功编译。

2.4 Matlab自身的编译器

Matlab自身的编译器可将Matlab的m文件转换为为C或C++的源代码以产生完全脱离

Matlab和Visual C++的混合编程

Matlab运行环境的独立的运用程序,在编译的过程中,如果调用Matlab工具箱中的函数,Matlab会自动联编所需要用到的其它m文件,并生成相应的C或者C++源代码。

此种方法的步骤比较繁琐,对Matlab编译器的命令参数和Visual C++的设置都需要详细的了解,作者将此种方法混合编程的过程介绍如下:

1) 用Matlab编译器编译m文件,根据m文件是否使用了图形相关的函数,命令参数分别如下:

没有使用图形相关函数:mcc–t –L C m文件、或者mcc –t –L CPP m文件分别得到C源代码和C++源代码。

使用了图形相关函数:mcc –B sgl –t –L C m文件、或者mcc –p –B sglcpp m文件分别得到C源代码和C++源代码。

2) Visual C++设置:在Tools/Options/Directories的Include Files中加入: MATLAB路径\EXTERN\INCLUDE\CPP

MATLAB路径\EXTERN\INCLUDE

Library Files中加入:

MATLAB路径\EXTERN\LIB\WIN32

MATLAB路径\EXTERN\LIB\WIN32\MICROSOFT\MSVC60

在Project/Setting/link的Input中,Object/Library modules文本框中加入libmmfile.lib libmatlb.lib libmx.lib libmat.lib libmatpm.lib sgl.lib libmwsglm.lib libmwservices.lib,这些lib是Visual C++运行Matlab编译的C/C++源代码所需要的库,在Ignore Libraries中有时候要加入msvcrt.lib,libcd.lib,这主要是看Matlab的库函数是否与Visual C++提高的函数产生冲突而定,在Win32 Application的Visual C++工程中一般需要在Ignore Libraries中加入msvcrt.lib,libcd.lib以解决警告信息。

在Project/Setting/C/C++中,Preprocessor definitions中加入MSVC,IBMPC,MSWIND;再在下拉框中选择Precomplied Headers,选中Automatic use of precompiled headers,在其中填入stdafx.h。

3) 添加Matlab编译后与m文件对应的.h或.hpp、.c或.cpp和bin目录(用到图形相关函数才有)复制到所建的工程中。

修改源代码,以MFC Appwizard(exe)工程为例:首先要添加相应的头文件,其次在InitInstance函数中加入:

libmmfileInitialize();

libmwsglmInitialize();

mlfHGInitialize(NULL,NULL);

在析构函数中加入:

mlfHGTerminate();

libmmfileTerminate();

libmwsglmTerminate();

然后在适当的位置添加需要Matlab类型代码或者调用的Matlab编译后的功能函数。

4) 编译调试,由于此方法设置比较复杂和灵活性比较大,所以调试必不可少的,要根据不同的错误提示做不同的改动。

2.5 调用外部程序

这种方法是先利用Mideva或者Matlab自身编译器直接生成EXE文件,然后在Visual C++的工程中通过CreateProcess()或Shell调用,常见的外部函数有shellexec()或winexec()。这种方法简单方便,但运行时出现一个控制台窗口,而且由于Visual C++和Matlab之间不能交互,通用性差,仅适用于Visual C++工程中调用Matlab实现图形显示的场合。

三、Visual C++和Matlab混合编程的问题总结

Matlab的运算功能强大、工具箱函数丰富,本设计只是对Matlab和Visual C++的集成作了一些简单的试验,应用于图像处理方面,并作了一些对比;但是目前两个开发工具的集成只能是比较简单、比较浅层的集成,要想进一步集成,Matlab或者Windows的内部调用机制要进一步完善,我们也要更进一步了解它们的内部机制。

Matlab和Visual C++的混合编程

参考文献:

1、Microsoft MSDN 在线帮助文档

2、Matlab帮助文档

3、孙兆林 《Matlab 6.X图像处理》 清华大学出版社 2002

4、何斌 马天子 王运坚 朱红莲 《Visual C++ 数字图像处理》 人民邮电出版社 2000

(指导教师 张小健 讲师)

本文来源:https://www.bwwdw.com/article/o3p1.html

Top