MATLAB与.NET混合编程实例(C#)
阅读原文时间:2021年04月23日阅读:1

我们为什么要应用MATLAB接口技术进行混合编程?
MATLAB使用一种脚本语言,它的执行是逐行解释执行的,也就是边解释边执行,程序中所有的变量都是MxArray来实现的,所以为了保证通用性,他的执行效率非常低,这就是我们常常看到的在开发一些复杂算法时,通常会发现程序执行的特别慢,虽然Mathworks公司已经在竭力提高M脚本文件的运算速度,但目前为止,效果仍然不能和同样功能的可执行程序相比 。而且,M文件不能脱离MATLAB这个应用程序环境,这就大大制约了程序的可移植性和通用性,因此,MATLAB不适合作为通用的编程平台。那么实现MATLAB与其他语言的混合编程就十分重要了,这有助于发挥MATLAB和其他编程语言各自的优势,降低开发难度,缩短编程时间,提高执行效率。

MATLAB的接口技术有什么?
 主要有9种:MATLAB Compiler, MATLAB引擎, MAT数据文件共享数据, 通过ActiveX, Mideva/Matcom, MATLAB数学库, MATLAB COM Builder, Excel Link, MATLAB Builder for Excel等。

ps: 上面的内容参考的一本书。

  本文主要说明一下MATLAB与.NET是怎样进行混合编程的,以C#为例,通过com组件的形式。  

我的机器的软件环境:
Windows 7 操作系统;MATLAB r2010a;visual studio 2010

  通过com组建的形式进行混合编程,如果机器上没有安装MATLAB,编译生成的软件照样可以使用,但是需要安装MATLAB提供的MATLAB Compiler Runtime ,这个软件在MATLAB的安装目录下:X:\\MATLAB\\R2010a\\toolbox\\compiler\\deploy\\win32 \\MCRInstaller.exe(X是MATLAB安装的盘符),如果你的电脑上安装了MATLAB,则不需要在重新安装这个软件。另外,不同的 MATLAB版本提供的MATLAB Compiler Runtime可能会不同,如果在另一台电脑上自己编写的软件运行有问题,可能是编译器的版本不同引起的。  

这个例子是平时上课的时候一个作业,我只公布关于混合编程部分的源代码。

首先来几张关于这个小软件的图片:

主界面

模拟计算的界面

绘图的界面

这里只有tabcontrol这个控件的作图用到了混合编程,其它三个picturebox里的图形使用GDI作出来的。
来一张混合编程作出来的图片:
混合编程

怎么样,很像是有个驱替前缘吧?事实就是如此。

使用混合编程,首先把MATLAB提供的MWARRAY类库添加进去 。在visual studio 2010中,新建好项目以后,在解决方案资源管理器中,右键单击“引用”-“添加引用”-“浏览”,MWARRAY.dll在X:\MATLAB \R2010a\toolbox\dotnetbuilder\bin\win32\v2.0中,浏览的时候找到这个组件,添加进去即可。它的作用是把 C#中的数组转化为MATLAB中的数组。并且需要在程序开始部分添加下面这句话:
using MathWorks.MATLAB.NET.Arrays;

本例中主要用MATLAB作图,因此还需要把作图组件添加到引用中,这就需要先写好程序,然后在MATLAB中进行编译,编译成.dll文件,和添加MWARRAY一样,添加到引用之中。

我们给画图的com组件起个名,叫DrawAss,下面主要讲 DrawAss组件的生成
首先把在C#中要实现的MATLAB的功能的函数写好,这里必须是函数文件,一般的M文件不可以。
我们以作压力分布曲面为例,其他类似。在MATLAB中编写程序如下:

function DrawP3D(P)
%绘制压力变换的3D图像

[m n]=size(P);
x=1:m;
t=1:n;
[x t]=meshgrid(x,t);
P=P';
meshc(x,t,P);
title('一维油水两相数值模拟压力变化');
xlabel('网格标号')
ylabel('时间步数')
zlabel('压力')

这段程序非常简单,没啥好说的。
然后再编写作含水饱和度及含油饱和度分布图像的函数,见下图:


一看函数的名字就知道是干啥的了。

下面就进行编译了。
单击MATLAB界面左下角的start-MATLAB-MATLAB Builder NE-Deployment tool,或者是直接在命令窗口直接输入deploytool,新建一个工程,名为DrawAss,target选择.Net Assembly即可。这样MATLAB会弹出一个窗口,在窗口上部,点击classes,新建一个类,默认的类名是class1,改为MWDraw,然后点击add files,把上图中的函数文件添加进去,点击build按钮(一个框,上面三个向下的箭头)编译即可。如果第一次进行编译,会出错,首先在命令窗口中输入mbuild -setup(注意有空格),然后选择1即可。
 这样就会得到一个文件夹DrawAss,我们需要的组件DrawAss.dll就在DrawAss\distrib中,按照添加MWARRAY的方法添加到引用中,当然也需要在程序开始部分添加下面一句话:
using DrawAss;

C#中的代码
下面的代码就是C#中进行调用这两个组件的代码:
代码不难,仔细斟酌一下就会明白了。我只在第一个上加上几句注释,其他的都一样

private void bntP_Click(object sender, EventArgs e)
{
int t = cbxP.SelectedIndex;
if (t == -1)
{
 MessageBox.Show("没有选择时间!", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
 double[] p = new double[m];
 for (int i = 0; i < m; i++)
 {
p[\i] = result[i, 2 * t];
//p[\i]这里本没有这个斜杠,但是和萃园的代码冲突,就加上了个斜杠
//后面的一样
 }
 t = t + 1;
 MWDraw myDraw = new MWDraw();//声明类的实例,了解C#朋友都明白
 myDraw.DrawPCurve((MWNumericArray)p, (MWNumericArray)t);
 //调用myDraw中的方法DrawPCurve作图,(MWNumericArray)p把C#中的数组p转
 //化为MATLAB中的数组
}
}

         private void bntSw\_Click(object sender, EventArgs e)  
         {  
             int t = cbxSw.SelectedIndex;  
             if (t == -1)  
             {  
                 &nbsp;MessageBox.Show("没有选择时间!", "提示",  
                         MessageBoxButtons.OK, MessageBoxIcon.Warning);  
             }  
             else  
             {  
                 &nbsp;double\[\] Sw = new double\[m\];  
                 &nbsp;for (int i = 0; i < m; i++)  
                 &nbsp;{  
                         Sw\[\\i\] = result\[i, 2 \* t + 1\];  
                 &nbsp;}  
                 &nbsp;t = t + 1;  
                 &nbsp;MWDraw myDraw = new MWDraw();  
                 &nbsp;myDraw.DrawSwCurve((MWNumericArray)Sw, (MWNumericArray)t);  
             }  
         }  

         private void bntSo\_Click(object sender, EventArgs e)  
         {  
             int t = cbxSo.SelectedIndex;  
             if (t == -1)  
             {  
                 &nbsp;MessageBox.Show("没有选择时间!", "提示",  
                         MessageBoxButtons.OK, MessageBoxIcon.Warning);  
             }  
             else  
             {&nbsp;                     
                 &nbsp;double\[\] So = new double\[m\];  
                 &nbsp;for (int i = 0; i < m; i++)  
                 &nbsp;{  
                         So\[\\i\] = 1 - result\[i, 2 \* t + 1\];&nbsp;                             
                 &nbsp;}  
                 &nbsp;t = t + 1;  
                 &nbsp;MWDraw myDraw = new MWDraw();  
                 &nbsp;myDraw.DrawSoCurve((MWNumericArray)So, (MWNumericArray)t);  
             }  
         }  

         private void bnd3D\_Click(object sender, EventArgs e)  
         {  
             int DMode = listBox1.SelectedIndex;  
             MWDraw myDraw = new MWDraw();  
             if(DMode==0)  
             {  
                 &nbsp;double\[,\] P = new double\[m, n / 2\];  
                 &nbsp;for (int i = 0; i < m; i++)  
                 &nbsp;{  
                         for (int j = 0; j < n / 2; j++)  
                         {  
                             P\[i, j\] = result\[i, 2 \* j\];  
                         }  
                 &nbsp;}  
                 &nbsp;myDraw.DrawP3D((MWNumericArray)P);  
             }  
             else if(DMode==1)  
             {  
                 &nbsp;double\[,\] Sw = new double\[m, n/2\];  
                 &nbsp;for (int i = 0; i < m; i++)  
                 &nbsp;{  
                         for (int j = 0; j < n / 2; j++)  
                         {  
                                 &nbsp;Sw\[i, j\] = result\[i, 2 \* j + 1\];  
                         }  
                 &nbsp;}  
                 &nbsp;myDraw.DrawSw3D((MWNumericArray)Sw);  
             }  
             else  
             {  
                 &nbsp;double\[,\] So = new double\[m, n / 2\];  
                 &nbsp;for (int i = 0; i < m; i++)  
                 &nbsp;{  
                         for (int j = 0; j < n / 2; j++)  
                         {  
                             So\[i, j\] = 1 - result\[i, 2 \* j + 1\];  
                         }  
                 &nbsp;}  
                 &nbsp;myDraw.DrawSo3D((MWNumericArray)So);  
             }  

  }  

该文引用:http://blog.sina.com.cn/s/blog_6bf019790100yh7h.html

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章