C#与matlab混合编程的研究与应用

C#与matlab混合编程的研究与应用

       matlab在矩阵的运算和处理上很有效率,因此在绘图上也是很强大的,几乎很少有一种语言能跟matlab绘图相比,但matlab也有自己的缺点,无法像C#和java那样简单的做出复杂的windows应用程序,虽然C#和java也能通过一定的算法实现很漂亮的二维三维绘图,但算是实为复杂,所以让我想到能不能利用接口技术实现C#/java和matlab混合编程,再者联系我们所学专业(石油应用)想到能否利用matlab来绘制地质方面的图像,在matlab绘图中三维绘图应用很广泛也很方便,如果能够很好的处理C#/java和matlab之间的数据传递的话就可以很轻松的利用C#调用matlab来绘制出利于分析地质问题的三维地质图像了.

因为是第一次尝试,所以先从简单的小的调用来开始——C#调用matlab绘制y=x^2曲线

       据我目前的知识加上网上查到的相关知识知道用matlab编写的函数可以编译成.net的dll动态链接库可以供C#调用,同样也可以编译成java的jar包供java调用,这两者在原理上相似,而重点都是在如何在两种语言之间进行数据的转换与传递。下面介绍我写的几个简单的调用步骤与实现代码:

调用步骤:

 

在matlab中编写函数

 

 

这个函数的功能很简单,就是画bar图形,在matlab中运行的结果如下:

 

然后利用matlab将其编译成C#可调用的dll文件即可供C#调用了,具体操作如下:

在matlab命令行中输入deploytool即可进入如右图所示的对话框中,给其命名,选择target为.NET Assembly等待编译即可,然后在matlab的工作区间中找到dll文件:

在C#程序中做测试,在新建的项目中添加引用:

 

       在这里是我体会比较深的一点,因为当时没有考虑到两个不同的语言之间的通讯问题,没有添加MWArray.dll文件导致出了很多问题,最后才添加进来,添加了这两个文件之后就可以在C#窗体应用程序中做测试了,在测试绘制bar图形之前我测试了绘制线条,在网上查到相关资料上说在matlab的文件中有相关的实例,找到后,我按照网上的做法做了测试,但是总感觉应用肯定不止这点,因此还测试了一个bar图形的绘制,感觉还不错,但还是有一个问题没有解决,在网上找了很多解决方法,还是出错,无法获取matlab绘图的句柄,无法将matlab绘制好的图形嵌入到C#程序的panel中,这是很头疼的一个问题,不过在这次的尝试中,我感觉学到了很多东西,每一种语言都有它自己的缺陷,不可能完美,如果能结合两种语言的优势,混合编写程序,肯定能起到事半功倍的效果。

       我是学习软件工程专业石油应用方向的,想到matlab的绘图在石油底层绘制,测井九条曲线的绘制等,再加上C#在开发上的优越性,因此C#和matlab的混合编程是很不错的,但在数值的转换上有需要进一步的研究。

效果展示:

 

C#和matlab在数值上的转换:

在matlab中用到最多数据类型就是矩阵了,matlab对于矩阵的处理效率很高,所以在图形的绘制上很有优势,而C#却在矩阵上的处理不如matlab,如果能想办法把数据在C#中做处理,先读出绘图中需要的数据,然后通过数据类型的处理,转换成matlab能处理的矩阵类型,那么就能够很好地利用matlab绘出很标准很利于分析的二维三维图形了。

在数值上的处理,我通过研究matlab在C#中的dll,利用反编译工具查看其构造函数发现,可以将C#中的数组强制转换成matlab中的矩阵类型,但有时候不小心会出错,因为在C#中数组下标是从0开始的,而在matlab中下标却是从1开始的,所以在转换的过程中如果不注意会经常出错,

假设在matlab中过一段代码绘制一个二次曲线的函数,然后编译成C#可调用的dll文件,类名为Calculater:

functiondrawgraph(coords)

plot(coords(1,:),coords(2,:));// 以coords矩阵的第1行的所有列为X坐标,第2行的所有列为Y轴。

在C#中编写代码:

//二维数组,Y=X^2

double[,]plotValue = new double[10, 2];

for (int i = 0;i < 10; i++)

{

plotValue[i, 0]= i;

plotValue[i, 1]= i * i;

}

//实例化Calculater对象

CalculatermyCalculater = new Calculater();

//调用drawgraph方法

myCalculater.drawgraph((MWNumericArray)plotValue);

C#的代码中说起来也非常简单,声明一个二维数组,使用for循环给每一个元素赋值,这个数组的第0列是X坐标的值,数组的第1列是Y坐标的值,两个坐标的关系是Y=X^2。

这里会出现一个问题,就是数值转换的问题,C#创建的数组是10行2列的,而drawgraph的函数想接收一个2行10列的数据,画的图总不是我想要的图,然后通过查看MWNumericArray各种构造方法其中有的构造函数可以用来实现这一转换:

publicMWNumericArray(MathWorks.MATLAB.NET.Arrays.MWArrayComplexity  complexity, params int[] dimensions) 输入的第一个参数是枚举型参数,有两个值分别是Real,另一个是Complex;然后输入矩阵的维数,由于有params关键字,所以可以创建指定大小的1维2维和3维矩阵。

//实例化Calculater对象

CalculatermyCalculater = new Calculater();

//使用构造方法,构造一个10行2列的实数矩阵

MWNumericArrayplotValue = new MWNumericArray(MWArrayComplexity.Real, 10, 2);

//注意该实数矩阵的下表从1开始

for (int i = 1;i <= 10;i++ )

{

plotValue[i, 1]= (i - 1);

plotValue[i, 2]= (i - 1) * (i - 1);

}

//调用drawgraph方法

myCalculater.drawgraph(plotValue);

反思:在C#中调用matlab绘图总是感觉效率特别低下,在java中稍微会好一些,可能是java是c++编写的,而matlab也是,估计是这个原因,所以在数值的转换上会快一些,但两种语言始终会出现一个问题,就是无法获取matlab绘图的窗体句柄,因此无法实现将matlab窗体嵌入到C#窗体中,如果能实现嵌入的话,肯定能得到很好的利用……

posted @ 2013-08-29 07:33  彬_hb  阅读(2076)  评论(2编辑  收藏  举报