Matlab是很丰富的一个资源,我在一个曝光机项目的一个算法中用到了Matlab的函数,在VS的不断升级过程中以及Matlab的各个版本变化,导致了我经常困惑了,这里还没有提到操作系统,32位还是64位。
下面我先介绍下我的环境:
windows8.1 64bit, Matlab 7.11.0(R2010b)-64bit,VS2012,vs2008
搭建好环境后,第一步先新建一个M函数, 我这里新建两个M文件,分别保存为函数名称multiply.m, makesquare.m文件。
function z = multiply(x,y)
z = x * y;
function y = makesquare(x)
y = magic(x);
1.1)新建Deploy tools
1.2) 建立工程名字,这里叫做TestCSharpCallMatlab,并选择生成.NET Assembly,路径可以更换。
1.3)添加一个类(DemoTest),并为这个类添加两个m文件。
1.4)点击右边的设置,选择要生成的.NET Framework的版本,我这里最高只有.NET3.5,就选择3.5.
在其他对话框里面还可以进行一些设置,这里就不介绍了。
1.5)点击编译按钮,就开始编译了,等待编译完成。
1.6)编译完成后,就生成了2个文件夹,其中distrib里面就有我们想要调用的dll了,具体里面什么内容,我们查看附件就可以了。
我们生成完动态链接库以后,就要如何调用了,下面我先直接使用VS2008来进行调用(匹配.NET 3.5),
新建一个winform程序,引用两个库,一个是MWArray(C:\Program Files\MATLAB\R2010b\toolbox\dotnetbuilder\bin\win64\v2.0),一个是生成的dll(C:\Program Files\MATLAB\R2010b\bin\TestCSharpCallMatlab\distrib\TestCSharpCallMatlab.dll).
然后using设置:
using TestCSharpCallMatlab;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
这里设置两个按钮调用2个函数,然后把结果显示在文本框中,代码如下:
1 private void button1_Click(object sender, EventArgs e) 2 { 3 try 4 { 5 DemoTest test = new DemoTest(); 6 int[] offset = {2}; 7 int[] ppp ={3}; 8 MWArray a = new MWNumericArray(1,1,offset); 9 MWArray b = new MWNumericArray(1,1,ppp); 10 MWNumericArray results = (MWNumericArray)test.multiply(a, b); 11 textBox1.Text = string.Format("2 * 3 = {0}", (int)results[1]); 12 13 } 14 catch (Exception ex) 15 { 16 17 MessageBox.Show(ex.Message); 18 } 19 } 20 21 private void button2_Click(object sender, EventArgs e) 22 { 23 try 24 { 25 DemoTest test = new DemoTest(); 26 int[] offset = {3}; 27 MWArray a = new MWNumericArray(1,1,offset); 28 MWNumericArray results = (MWNumericArray)test.makesquare(a); 29 StringBuilder sb = new StringBuilder(); 30 sb.AppendLine(string.Format("{0}, {1}, {2}", results[1], results[2], results[3])); 31 sb.AppendLine(string.Format("{0}, {1}, {2}", results[4], results[5], results[6])); 32 sb.AppendLine(string.Format("{0}, {1}, {2}", results[7], results[8], results[9])); 33 textBox2.Text = sb.ToString(); 34 } 35 catch (Exception ex) 36 { 37 MessageBox.Show(ex.Message); 38 } 39 40 }
这里要注意的就是类型的转换,以前我因为转换问题,出现过too many output arguments的错误。
最终显示结果如下:
在这里,VS的设置为any cpu即可。VS2008的Demo代码链接如下:
https://files.cnblogs.com/files/monkeyZhong/TestCSharpCallMatlabApplication2008.zip
https://files.cnblogs.com/files/monkeyZhong/TestCSharpCallMatlab.zip
但是VS2012就容易出现问题,归根结底就是要修改VS2012的目标框架为.NET Framework3.5,这样才会正确,
否则就会出现这样的错误:已停止工作。
当然C#调用Matlab的方法不止这一种,还有几种其他的方法,这里就不在这里说了。