最近正在给客户作的我的项目,要求实现C#与Matlab之间的调用,即C# winform界面收集用户输入的参数,将参数传递给Matlab的算法计算,Matlab函数返回的结果显示在winform界面上。算法
网上此类的文章较多,但本身在实现过程当中仍是有些差异,因此在项目进行以前,本身写了一个测试的例子来实现C#对Matlab函数的调用。ide
一. 测试用例简介函数
功能:Matlab函数计算两个数值a与b的和,a与b的值由C#提供,和值c经Matlab计算得出后,返回给C#工具
环境:Microsoft Visual Studio 2008测试
Matlab R2009a(Version 7.8.0.347)ui
备注:由官网可知,Matlab对相似其余程序调用都提供了很好的支持,这里没有选择VS版本大于Matlab版本,是由于担忧Matlab版本只支持本身以前的VS版本。spa
二. 实现步骤命令行
1. 实现Matlab函数设计
A. 打开Matlab R2009a,新建testAdd.m文件code
B. testAdd.m中实现加法函数
1 function y = testAdd(a, b) 2 y = a + b;
2. 编译testAdd.m,获得DLL文件,以便由C#引用
A. 在Matlab命令行中输入"deploytool",便可弹出"Deployment Tool"工具窗口
在网上看不少资料,执行"deploytool"命令以前都须要安装Matlab编译器(命令:"mbuild -setup"),但我不这样作,也可编译。怀疑是否与我将VS,Matlab都装在一台机器有关。另外即使我执行这安装命令,也找不到正确的编译器。总之,我并无按照网上教程,直接"deploytool"便可。这也提醒本身:实践事后,才知是否正确,不要盲目遵从别人方法。
B. 编译DLL,须要在"Deployment Tool"工具窗口中新建Deployment project
这里我建了名为"test"的工程,选择project类型时,应选择.NET Component,由于这里我须要其做为C#的引用。同时注意这里的工程名,便是你编译出DLL的名称,同时C#程序调用时,"Test"即为封装Matlab函数的类名。他将你的工程名,首字母大写用为高级语言中的类名。
C. 配置"test" project
首先将testAdd.m添加到test工程下Test文件夹中(右击Test,选择Add File)(注意:这里不要使用中文路径,详见下方六.测试过程当中Bug记录)。
其次选择Setting,在设置中,配置.NET Microsoft Framework,由"Default"改成"2.0",不能用默认。网上说法是不然编译出的DLL会有问题。
注意:这里网上许多资料讲,要将Assembly Type设置为Shared,但我发现若是这样,必需要提供Encryption Key的文件路径,这个就无法提供了。因此我并无这样作,事实上没有影响。疑惑的地方。
D. 点击"Build"编译文件(以下图所示)
便可在test\src路径下获得编译后的DLL文件
3. 实现C#程序,调用Matlab编译出的DLL
A. C#项目中,导入Matlab DLL引用
导入的文件:test.dll, testNative.dll, MWArray.dll(%matlabpath%\toolbox\dotnetbuilder\bin\win32\v2.0,MWArray是用于C#与Matlab之间的数据交换类,传值,取结果都用到它)
B. 实现C#调用代码
1 using System.Data; 2 using System.Drawing; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6 using MathWorks.MATLAB.NET.Utility; 7 using MathWorks.MATLAB.NET.Arrays; 8 using test; 9 10 namespace testMatlab 11 { 12 public partial class Form1 : Form 13 { 14 public Form1() 15 { 16 InitializeComponent(); 17 18 label6.Text = ""; 19 } 20 21 private void button1_Click(object sender, EventArgs e) 22 { 23 //Get input number from UI 24 int iTextBox1 = int.Parse(textBox1.Text.ToString()); 25 int iTextBox2 = int.Parse(textBox2.Text.ToString()); 26 27 MWArray result = null; 28 MWNumericArray a = new MWNumericArray(iTextBox1); 29 MWNumericArray b = new MWNumericArray(iTextBox2); 30 31 32 //call function testAdd, provided by Matlab 33 Test t = new Test(); 34 result = t.testAdd((MWArray)a, (MWArray)b); 35 36 37 int y = ((MWNumericArray)result).ToScalarInteger(); 38 39 //show result in UI 40 41 textBox3.Text = y + ""; 42 label6.Text = "Get the result by Matlab DLL, Answer: " + y; 43 } 44 } 45 }
三. 执行C# winform程序,验证计算结果,肯定是否执行了Matlab函数调用
1. 输入初值
2. 获得结果
四. 小结
由此,可实现C#对Matlab算法的调用。固然这里只是本身开发须要时,设计的一个小例子。因为Matlab计算,输入与结果须要大量的矩阵,那C#与其之间的数据交换也是经过MWArray进行,只要遵循接口规范,均可以实现。这里再也不研究,网上资料也不少。
五. 完整的测试例子附件
Matlab函数:http://files.cnblogs.com/KevinSong/testMatlab.zip
C#程序:http://files.cnblogs.com/KevinSong/Test.zip
六. 测试过程当中Bug记录
1. 调用DLL时,程序报错"MathWorks.MATLAB.NET.Utility.MWMCR.mclCreateComponentData,错误描述是:传递给系统调用的数据区域过小"
解决方法:不能使用中文路径的.m文件,可能会有诡异的问题产生
参考连接:http://hi.baidu.com/ssemo/item/4caab7f3a0765ec20dd1c888
虽然网上参考资料不少,但通过本身实践,仍是发现一些不一样的小地方。项目进行前,经过一个小的测试例子来证实技术路线可行。但愿对须要的同窗有帮助。抛砖引玉:-)
Best Regards
Kevin Song