COM组件在实现VB.net 调用MATLAB中的应用

第一篇博文,有空在放图!

1.      通过MATLAB引擎(Engine)---接口函数

提供了一组Mat lab API函数,用户不必关心MATLAB引擎是如何实现的,只要调用这些函数即可。正是通过这些API函数实现应用程序进程之间的传递函数,从而实现Mat lab与VC的混合编程。VC的C语言或C++语言向Mat lab引擎传递命令和数据信息,通过调用MATLAB引擎在后台与MATLAB服务器建立连接,实现动态通信。这种处理方法不要求链接整个Mat lab,只需嵌入必要的Mat lab引擎库,节省了大量的系统资源,使应用程序整体性能更好,处理效率更高,但这种混合编程的方法需要MATLAB在后台适时运行不能脱离Mat lab环境,否则影响了程序的通用性,因此这种方法在实际开发过程中很少采用。

例子:在vb.net 的Form1里设置3个Button和一个PictureBox,代码如下:

Public Class Form1

    Dim strmatlab As String

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage

 

    End Sub

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

 

        Dim matlab As Object

        ' 建立matlab应用()

        matlab = CreateObject("matlab.application")

        ' 最小化matlab命令窗口()

        matlab.minimizecommandwindow()

        'matlab语句()

        strmatlab = "t=2:0.2:4*pi;y=sin(t);plot(t,y)"

        '执行matlab算法()

        matlab.execute(strmatlab)

        '生成一个jpg的图形c:\test1.jpg

        matlab.execute("print( gcf,'-djpeg','d:\test1.jpg')")

             

        ' 退出matlab, 释放资源

        matlab.quit()

        matlab = Nothing

        '显示在图片框()

        PictureBox1.Image = New Bitmap("d:\test1.jpg")

    End Sub

 

    '显示饼图

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

 

        Dim matlab As Object

        matlab = CreateObject("matlab.application")

        strmatlab = "sale=[100 400 150 250 500];pie3(sale,[0 0 1 0 0],{'公司a','公司b','公司c','公司d','公司e'})"

        matlab.execute(strmatlab)

        matlab.execute("print( gcf, '-djpeg', 'd:\test2.jpg')")

        matlab.quit()

        matlab = Nothing

        PictureBox1.Image = New Bitmap("d:\test2.jpg")

 

    End Sub

    '显示三维螺线图

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        Dim matlab As Object

        matlab = CreateObject("matlab.application")

        strmatlab = "t=0:0.2:4*pi;plot3(sin(t),cos(t),t)"

        matlab.execute(strmatlab)

        matlab.execute("print( gcf, '-djpeg', 'd:\test3.jpg')")

        matlab.quit()

        matlab = Nothing

        PictureBox1.Image = New Bitmap("d:\test3.jpg")

 

    End Sub

 

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click

        '显示立体波浪图()

        Dim matlab As Object

        matlab = CreateObject("matlab.application")

        strmatlab = "[x,y,z] = peaks(20);surfc(x,y,z);colormap hsv;axis ([-2 4 -6 8 -10 6])"

        matlab.execute(strmatlab)

        matlab.execute("print( gcf, '-djpeg','d:\test4')")

        matlab.quit()

        matlab = Nothing

        PictureBox1.Image = New Bitmap("d:\test4.jpg")

    End Sub

 

End Class

 

 

 

缺点:需要安装MATLAB在后台运行!!缺乏独立性!

2. 通过组件对象模型(com)建立动态链接库DLL实现混合编程

DLL是动态链接库的英文缩写,是一个可执行的二进制文件。把很多通用的功能放在DLL 中,可供多个应用程序调用,而不是每个应用程序在连接时都要增加一个库中目标代码的拷贝。通过MATLAB自带的Compiler编译器,可以把由Mat lab编写的m 函数文件编译成动态链接库(dl1)。或者通过Mat lab提供的组件功能,运用VC+十向导自动生成m文件的动态链接库。在VS程序中调用封装的函数,实现数值算法的运用。这种方法只需在开发和发布中包含其生成的动态库就可以了,可以使程序脱离MATLAB可以整体减少文件外部存储空间的占有量,并实现了代码共享。

注:必须用MATLAB 2008b以后的版本,用MATLAB 2008a在创建对象时候会出现“System.TypeInitializationException”一类的异常,这应该是Mat lab 2008a创建的DLL的问题。

壹、 安装MATLAB Compiler Runtime v7.14

在MATLAB 安装目录(D:\Program Files\MATLAB\R2010b)下找到toolbox\compiler\deploy\文件夹,在其win32(64位版本则是在win64)文件夹下面找到MCRInstaller.exe。它就是MATLAB Complier Runtime(MCR)安装程序,安装它。

安装后,在MCR安装目录(D:\Program Files\MATLAB\MATLAB Compiler Runtime\v714)下找到runtime\文件夹,win32(64位版本则是在win64)文件夹下面找到mwcomutil.dll,注册它。具体办法是在“开始菜单\程序\Microsoft Visual Studio 2005\Visual Studio Tools”中找到“Visual Studio 2005 命令提示”的快捷方式,运行它。在这个命令行环境下,可以运行注册COM件的命令行程序。用法是

>> "D:\Program Files\MATLAB \MATLAB Compiler Runtime\v714\runtime\win32"

>>D:

>> regsvr32 mwcomutil.dll

贰、 在MATLAB中编写程序

一、 编写基本程序(.m 文件)—写成函数形式

例子:picc函数

function picc()

     y='d:\test1.jpg';

     pic= imread(y);

    picnew = imresize(pic, [240 360],'bicubic');

    imwrite(picnew,'d:\picc1.jpg');

end

二、 配置MATLAB Builder NE

在MATLAB命令行窗口,运行mbuild设置MATLAB Builder编译程序:

 

 

 

请替换成实际安装目录

 

注:如需进行mex 命令设置,方法同上。(在MATLAB的命令窗口中输入>> mex -setup)

叁、 通过COM组件混合编程

一、 生成普通COM 组件

运行Deployment Tool后出现下面的窗口:

 

>>deploytool

 

 

 

注:在matlab6.0版本之前是comtool

在新弹出的窗口(可能自动停靠到右边,可以单击Undock按钮分离)运行New Deployment Project。选择MATLAB Builder NE下的Generic COM Component。在Name处输入picc.prj,单击OK。

先单击add class,在选择Add File,添加刚才新建立的文件。单击Settings按钮,可以选择工程属性,如组件名称和版本等等。运行菜单“Tools\Build”。MATLAB会自动编译这个工程。

打开工程目录(D:\My Documents\MATLAB\picc\picc\),该目录下的src\保存了COM件的C++源代码,在distrib\文件夹下保存了可发布的DLL文件。

 

打包组件及MCR

    编译结束后产生的COM组件只能在当前计算机上使用,为了能够把它发布到其他计算机上使用,还需要其他一些支持文件。另外,COM组件不同于普通的DLL文件,COM组件必须注册后才能在计算机上使用。选择package命令,deploytool将会把发布该组件所需要的所有文件打包到一个和工程同名的可执行文件中。这里可以选择是否在打包文件中包含MCR。MATLAB产生的COM组件必须运行在MCR环境。如果目标计算机上没有安装MCR,那么在打包组件的时候最好选择包含MCR,这样在打包文件中就会包含MCR的安装文件。打包完成后将会在distrib中产生.exe的可执行文件,这是一个可以自解压的压缩文件。其中包含4个文件:_install.bat,dll文件,ctf文件,MCRInstaller.exe。把产生的.exe文件复制到需要发布的计算机上运行。结果将会把这四个文件解压,并执行_install.bat,这是一个DOS批处理文件,查看_install.bat的内容后可以发现_install.bat将会运行MCRInstaller.exe来安装MCR,并且在系统中注册组件文件。

 

 

二、 注册COM

注册可发布的DLL文件(MyAdd_1_0.dll)。在Visual Studio 2005命令提示环境下,运行:

>> cd "D:\My Documents\MATLAB\picc\picc\distrib"

>>D:

>> regsvr32 picc_1_0.dll

 

注册成功将得到类似“MyAdd_1_0.dll 中的 DllRegisterServer 成功。”的信息。

 

 

肆、 在VB.NET中编写程序调用COM组件

在VB.NET中创建一个项目,在“解决方案资源管理器”视图中添加引用。在COM标签中找到组件名称为MyAdd 1.0 Type Library的项,单击确定。则引用文件夹下就多了两项:MWComUtil和picc。

 

 

 

添加完以后就可以直接在程序中进行调用。

代码实例:

Public Class Form1

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim img2 As New picc.picc

            '调用MATLAB COM

 

        img2.picc()'调用MATLAB函数

'调用MATLAB函数有参数的话,是(NO,input,output1,oput2,…)其中NO是输出参数的个数

        Dim x As Image = Image.FromFile("d:\picc1.jpg")

        PictureBox1.Image = New Bitmap(x)

      

    End Sub

 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage

    End Sub

End Class

 

Result如下:

 

 

注意事项以及相应问题解决

  1. 在编译dll时,需要机器安装有C或C++编译器,比如安装VC6.0
  2. MATLAB启动Deplottool工具之前,还需要利用mbuild –setup 命令对compiler设置,将compiler设置成C++或C语言对应的compiler,而不是MATLAB自带的compiler.

PS:前两条如果没有做到的话,在deploytool生成界面往往出错,无法生成dll等相应的文件。

  1. 如果出现其他一些小问题,尝试重启Visual Basic 或是MATLAB,在或者重启电脑。

4. 在使用COM组件时,出现80040154错误。当使用regsvr32 [dll名]时,出现LoadLibrary("…") 失败 - 找不到指定的模块。

原因:某次加载该模块之后,手动修改注册表,注册信息被破坏。

解决方法:打开src文件夹下的idl文件,将uuid项的8-4-4-4-12位序列号记下来,打开注册表编辑器,查找所有刚才记下的uuid序列号,悉数删除。如不放心,则可以继续查找所有和工程有关的关键字,悉数删除,问题即得到解决。

 

  1. 在MATLAB编译时出现

Error: An error occurred while shelling out to mbuild (error code = 1).

Unable to build executable (specify the -v option for more information).

??? Error using ==> mcc

Error executing mcc, return status = 1.

解决方案:往系统环境变量path添加: matlabroot\bin;

--注,这里matlabroot指的是matlab根目录,再编译,还是不行,重启matlab,再编译,OK.具体方法如下:

 

在桌面上右键单击“我的电脑”图标出现以下菜单

 

单击“属性”菜单项,出现“系统特性”对话框,单击“高级”选项卡,如下图所示在上图中,单击“环境变量”按钮,出现“环境变量”对话框, 添加系统变量 matlab 值为 matlab的安装路径,如下图所示

 

 

在环境变量 path 中加入matlabroot\runtime\win32 ,如下图所示

 

 

按“确定”完成设置后, 重启计算机或注销当前用户 ,即可应用新设置。

 

 

 

  1. 若之前将编译生成的文件打包发布到没有MATLAB的电脑上时,没将mex打包进去,也可用此种方法.

先在 $MATLAB\toolbox\compiler\deploy\win32下找MCRInstaller.exe(76M左右)文件

然后在没有装MATLAB的机子上安装MCRInstaller到D:\MATLAB Component Runtime

(目录中,最好不要有空格,如用 D:\MCR 就可以了)

设置环境变量,右键点击“我的电脑”-》属性-》高级-》环境变量-》新建

变量名:Path   

变量值:D:\MCR\v70\runtime\win32

然后运行exe文件,每次都是出现DOS界面后,几秒钟就自动关闭了

GUI界面一次都运行不出来,也没有错误信息提示

解决办法:

{ 因为MATLAB需要用到处理器的数学运算部分(MATLAB默认用的是INTEL的数学处理单元),故需要设置一下BLAS(Basic Linear Algebra Subroutines,就是"基础线性几何子程序"的意思)环境变量.  首先请确认你的MATLAB的文件夹中有如下文件:atlas_Athlon.dll(AMD系列的请用这个),   atlas_P4.dll(P4的用这个),atlas_PIII.dll(P3的用这个),atlas_PII.dll(P2的用这个),这些是对应处理器的数值运算优化文件 }

先找到 $MATLAB7\bin\win32目录下的atlas_Athlon.dll(AMD系列CPU使用)和atlas_P4.dll(奔4用)文件,放到MCR目录中(随便),然后设置环境变量

变量名:BLAS_VERSION

变量值:D:\MCR\v70\atlas_Athlon.dll

 

REF:

 

 

http://hi.baidu.com/pengjun/blog/item/33661f17653f99094b90a705.html

 

http://wenku.baidu.com/view/6da13dfd910ef12d2af9e722.html

 

http://wenku.baidu.com/view/83f0c57f5acfa1c7aa00ccba.html

 

http://blog.sina.com.cn/s/blog_60abf0b60100ffhi.html

 (

http://hi.baidu.com/%C2%E4%CB%AE%C9%F1/blog/item/ca6f766cf5455cd680cb4a2e.html

 

http://www.matlabsky.com/thread-10041-1-1.html

 

http://www.matlabsky.com/thread-11710-1-1.html

 

http://lingchuangsong.blog.163.com/blog/static/12693232201032122430285/

 

<<在VB 开发环境中调用由MATLAB 函数转化的DLL>> 冯 旭

 

posted on 2012-02-20 16:55  乐宁  阅读(2027)  评论(0编辑  收藏  举报