初步探索如何使用Visual C#调用Matlab

Matlab 2007a, 2007b, 2008a, 2008b等都对开发独立于Matlab运作平台的Matlab应用程序有很好的支持。网址mathworks.com/products/compiler/demos.html 下提供了一些Matlab程序展开应用的实例,其中把纯的Matlab程序转换成独立执行的应用程序显得很简单。比如链接mathworks.com/products/demos/compiler/deploytool/index.html提供了如何把.m文件转换成独立运行的.exe可执行文件。由于用Visual C#调用Matlab的资料不多,经过初步探索,本文对这个问题用一个实例做个说明。

需要的工具:Matlab,Matlab Builder NE Toolbox,Matlab Compiler Toolbox, Visual C#

首先编写一个简单的Matlab函数,如下,并存为sumab.m(默认时存到Matlab的默认工作目录下)
function [tsum] = sumab(a, b)
tsum = sum([a,b]);

下面说明如何用VC#来调用这个函数。
在Matlab的Command Window下运行"mbuild –setup" 和 "deploytool",详细步骤参见blog.sina.com.cn/s/blog_4b94ff130100d4uf.html。 一般情况下,运行"mbuild –setup"时,让系统自动搜索编译器就可以了。deploytool运行后,取一个工程名test_combination_matlab_c,选择.NET Component,会生成一个新工程。把sumab.m 加入到新工程中,然后Build,工程目录下的Distrib目录里就会有test_combination_matlab_c.dll,可以供VC#使用。也可以Build Matlab里面自带的库函数,就如例子blog.sina.com.cn/s/blog_4b94ff130100d4uf.html 所做的。
打开Visual Studio, 新建一个VC#工程,笔者建的是Test项目。建好后,在Solution Explorer里,鼠标右键单击References->Add References->Browse, 加入生成的test_combination_matlab_c/Distrib/test_combination_matlab_c.dll;重复操作,加入Matlab目录下的另一个dll文件,/toolbox/dotnetbuilder/bin/win32/v2.0/MWArray.dll。

上面把该有的环境都设置好了,剩下的就是编程了。打开VC#工程里的主文件UnitTest1.cs,如果用其他类型的项目,相应打开项目的主文件。文件的开始部分加入
using MathWorks.MATLAB.NET.Arrays;
如要画图,加
using MathWorks.MATLAB.NET.Utility;
在主文件的主程序 public void TestMethod1() 里,加
MWArray a = 1, b = 2, c;
test_combination_matlab_c.Test_combination_matlab_c sumob = new test_combination_matlab_c.Test_combination_matlab_c();
c = sumob.sumab(a, b);
在Debug时,加入BreakPoint,配合Quick Watch,就可以看到c值为3.

这样,一个简单的调用程序就编好了。如果是数组矩阵,可以如下编写:
MWNumericArray aa = new double[2, 2] { { 1, 2 }, { 3, 4 } };
MWNumericArray bb = new double[2, 2] { { 1, 2 }, { 3, 4 } };
MWArray cc;
cc = sumob.sumab((MWArray)aa, (MWArray)bb);
注意数据类型的转换double<->MWNumericArray<->MWArray,参照网址
hi.baidu.com/adda/blog/item/c19bd33f3d87a6c77d1e714f.html

如果输入数组矩阵复杂,可以先在Matlab定义,再输入到VC#中。一个简单的输入如下所示,并存之为definematrixes.m
function [a, b] = definematrixes()
a = [1 2;3 4];
b = [3 4;5 6];
把definematrixes.m加入deploytool当前工程(test_combination_matlab_c.),重新build之后,转到VC#的项目,在主程序中加入下面代码:
MWArray aaa, bbb, ccc;
MWArray[] tempmatrix;
tempmatrix = sumob.definematrixes(2);
aaa = tempmatrix[0];
bbb = tempmatrix[1];
ccc = sumob.sumab(aaa, bbb);
这样,在Debug时,可以看到ccc={4,6,8,10}。这里有个小问题没解决,aaa.Dimension和bbb.Dimension都是2*2,不知为何,ccc就成了1*4了。如果没有好的方法,可以用Matlab的reshape函数把1*4维变回2*2维的矩阵—只是要把reshape也加入到deploytool 的工程test_combination_matlab_c中。

对单一数据(非数列和矩阵),笔者用form的方法实现了用户的输入输出。首先,新建一个基于Windows Form的项目,在Form里面,加入三个Label,三个Textbox组件以及一个Button组件(组件的大小位置刚开始可以随意些),再把下面的程序拷贝进Form1.cs即可—同样的要在References里头加入MWArray.dll和test_combination_matlab_c.dll。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
namespace Matlab_csharp_Forms_Application
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
     this.label1.Visible = false;
            this.textBox1.Visible = false;
            this.label2.Visible = false;
            this.label3.Visible = false;
        }
}
        private void button1_Click(object sender, EventArgs e)
        {
            MWArray a = 1, b = 2, c;
            test_combination_matlab_c.Test_combination_matlab_c sumob = new test_combination_matlab_c.Test_combination_matlab_c();
            try
            {
                a = System.Convert.ToDouble(this.textBox2.Text);
                b = System.Convert.ToDouble(this.textBox3.Text);
                c = sumob.sumab(a, b);
                this.label1.Visible = true;
                this.textBox1.Visible = true;
                this.textBox1.ReadOnly = true;
                this.textBox1.Text = c.ToString();
                this.label2.Visible = false;
                this.label3.Visible = false;
            }
            catch (System.FormatException)      
            {
                this.label1.Visible = false;
                this.textBox1.Visible = false;
                this.label2.Visible = true;
                this.label3.Visible = true;
                // Statements for handling the exception
            }
        }
}

由于不清楚Visual C#如何显示数列和矩阵,大的数据可能输出到Excel或SQL会是不错的选择,至于输入,也许可以考虑在Matlab中写输入数据的函数(如上所述);熟悉VC#者或许可以给出适合的答案。

你可能感兴趣的:(C#,matlab,Build,button,compiler,textbox)