C#和MatLab的混合編程,充分利用了winform的直觀顯示和matlab的強大計算能力。在此以一個小例子的形式給你們講述一下兩者混合編程的實現。編程
1、軟件的配置說明c#
C#版本:VS2010;MatLab版本:MatLab2011a數組
2、製做matLab的C# dll文件ide
2.1首先寫一個M文件(實現你想要的函數執行形式)函數
以網上down了一個M文件(實現基本的繪圖功能),內容見下表,ui
function test(h,D) for x=-10:0.1:10, if x>D y=h; hold on; plot(x,y) elseif x<-D y=-h; hold on; plot(x,y) else y=h/(D*x); hold on; plot(x,y) end end
2.2 建立製做的dll文件的工程spa
在MatLab的命令窗口中,輸入deploytool,或者利用菜單選項,file-new-deployment project打開建立dll文件的工程建立窗口,以下圖所示。.net
在圖中,主要分爲如下三部分,Name:你想要命名的名字,prj是工程的後綴(通常不忽略);location:建立工程的儲存位置;type:針對c#而言,咱們須要選擇.net assembly這一項;點擊Ok選項,工程已經建立完畢。下一步就是向工程中加入你想要的方法等元素。debug
2.3 向所建工程中添加對應的元素3d
上述過程當中,就至關於在C#中建立了Untitled2的命名空間,須要在此添加對應的類和方法。基於上述的例子,下一步,咱們在窗體菜單中 destop-.netAssembly-點擊選擇,見下圖所示。
在上面Classes是你本身對應編寫了一個類,而後向裏面添加Add files,也就是你以前編寫的M文件,通過編譯以後,就在對應的工程文件中,造成你所須要的dll文件。下一步咱們如何在C#中利用對應的dll文件。
3、如何在C#中利用Matlab製做的dll文件
3.1首先,將matlab中對應的剛編寫好的untitled的dll文件,同時從C:\Programs\Files\MatLab\R2011a\toolbox\dotnetbuilder\bin\win64\v2.0中拷貝出MWArrary.dll和ManagedCPPAPI.netModule三個文件拷貝到C#編寫的工程文件中去,C#編程文件的debug文件中。在這裏特別說明的一點是:最後一個文件在matlab2011a中沒有找到對應的文件,發現並不影響程序的執行。
3.2在C#的工程中,咱們在引用中----添加對彼此dll文件的引用。見下圖
3.3命名空間的引用 using.....的書寫
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using Untitled1;
4、最後,在C#中如何引用這些matlab提供的計算模塊的功能實現
4.1 在C#中調用MatLab的函數是最重要的是函數變量之間的傳遞是如何實現的?
包括如下幾個問題:a、將C#的參數帶入到matLab的函數的參數中,將C#的參數轉化成對應的MWArray類型。
b、如何將Matlab函數返回的類型,轉化成C#對應的函數類型。
4.2 MWNumericArray是MWArray和c#中數據的中間類,實現C#與matlab間傳遞參數的功能
a.double型、int型等數值類型的變量傳遞
MWNumericArray i = null, result = mydouble;
i=4;
myClass myclass = new myClass(); //實例化
result = (MWNumericArray)myclass.myfunc(i);
b.字符串(須要用到MWCharArray和MWArray轉換)
MWCharArray FileName = myString;
MWNumericArray sensitivity;
sensitivity = (MWNumericArray)myClass.myAlgorithm((MWArray)FileName);
c.多個輸出參數組成的數組
MWNumericArray out_Arr = (MWNumericArray)out_Args[1]; //取出第一個參數返回的數組(matlab返回的數組下界是從1開始的)
取出數組中的一個元素值
mydouble=out_Arr[i].ToScalarDouble();
如上面例子ToScalarDouble一類的toXXXX等方法還有許多。
d.result.toArray能夠把matlab返回的矩陣變成C#的n x m數組,eg:
double[,] csArray= (double[,])result.ToArray(MWArrayComponent.Real);
e.將數組傳入Matlab(和傳遞單個數值的方法同樣)
double[,] dbx = new double[2, 2] { { 1, 2 }, { 3, 4 } };
MWNumericArray x=dbx;
myclass.picture(x);
testz.testzclass st = new testz.testzclass(); MWArray[] max = st.testz(2); MWNumericArray x1 = (MWNumericArray)max[0]; MWNumericArray x2 = (MWNumericArray)max[1]; double[,] location1 = (double[,])x1.ToArray(MWArrayComponent.Real); double[,] location2 = (double[,])x2.ToArray(MWArrayComponent.Real); label1.Text = location1[1,2].ToString(); 其中的M文件: Code function [x1,x2]=testz() x1=[1 2 3; 4 5 6; 7 8 9;]; x2=[9 8 7; 6 5 4; 3 2 1;]
經常使用的轉換函數:
① public Array ToArray(MWArrayComponent component);
將M類型轉換成C#的Array類型,而後能夠直接轉換成其它類型的數組。
② public byte ToScalarByte();
將M類型轉換成C#的字節類型;
③ public double ToScalarDouble();
將M類型轉換成C#的雙精度類型;
double temp = ((MWNumericArray)(mwArgout[0])).ToScalarDouble();
④ public float ToScalarFloat();
將M類型轉換成C#的單精度類型;
⑤ public int ToScalarInteger();
將M類型轉換成C#的整型類型;
⑥ public long ToScalarLong();
將M類型轉換成C#的長整C/C++/C#數據型類型;
⑦ public short ToScalarShort();
將M類型轉換成C#的短整型類型;
⑧ public override string ToString();
將M類型轉換成C#的字符串類型;string arror = mwArgout[2].ToString();
⑨ public Array ToVector(MWArrayComponent component);
將M類型轉換成C#的Array類型,而後能夠直接轉換成其它類型的數組。
下面使用調試過的代碼示例表述①⑨兩個函數的區別:
①
double[,] Temp1 = new double[1,3];
Temp1= (double[,])((MWNumericArray)mwArgout[1]).ToArray(MWArrayComponent.Real);
⑨
double[] s1 = new double[2];
s1 = (double[])((MWNumericArray)mwArgout[1]).ToVector(MWArrayComponent.Real);
從以上代碼能夠看出:函數①獲得了二維數組,而⑨則是獲得了一維數組。轉換成C++/C#數據類型後,它們的維數均爲從0開始。
最後總結:
C++/C#數據類型到M類型
此方向轉換十分簡單。
若是C++/C#數據不是數組,
直接將值傳遞給已經初始化的MWArray數組中的成員
直接將數據類型賦值給已經初始化的MWNumericArray變量。
直接將字符串類賦值給已經初始化的MWCharArray變量。
若是是數組類型:
直接賦值給MWNumericArray變量;
賦值給MWArray變量,則在前面加上類型轉換如:(MWNumericArray)進行強制轉換。
總之,MWArray是總類型,其它的以MW開頭,以Array結尾的變量類型均可以直接對它進行賦值或取值。
M類型到C++/C#數據類型
MWArray
M類型,它是M文件的編譯後內部的標準類型,一切C++/C#類型都要最終轉換成此類型,方可做爲參數調用M語言函數。
MWCharArray
M的字符串類型,使用它能夠將M中的字符類型轉換成C++/C#的字符串類型。
MWNumericArray
MWNumericArray是MWArray與C#等語言的轉換中間類型。
上述整理參考了文獻出自http://zxfcool2000.blog.163.com/blog/static/31852320101117111555598/
在實現過程當中遇到的問題:
錯誤信息:「未能加載文件或程序集「MWArray, Version=2.11.1.0, Culture=neutral, PublicKeyToken=e1d84a0da19db86f」或它的某一個依賴項。試圖加載格式不正確的程序。」
解決方案:將C#項目屬性從x86->x64就好了
補充一個例子的應用:
M文件:
function [x1,x2]=test(x3) x1=[1 x3*x3 x3; 1-x3 5 6; 7 8 9;]; x2=[9 8 7; 6 5 4; 3 2 1;];
在C#中造成的幾種函數形式以下:
public MWArray test();
public MWArray[] test(int numArgsOut);
public MWArray test(MWArray x3);
public MWArray[] test(int numArgsOut, MWArray x3);
public void test(int numArgsOut, ref MWArray[] argsOut, MWArray[] argsIn);
因此在C#中能夠選擇不一樣的形式調用,其中numArgsOut指的是輸出參數的個數 argsOut:輸出參數,固然儘管C#中泛泛提出了幾種函數形式,確只有第3,4,5是可使用的(結合本身寫的M文件內容)
脫離matlab安裝的環境下,如何實現程序的運行自如:
經過com組建的形式進行混合編程,若是機器上沒有安裝MATLAB,編譯生成的軟件照樣可使用,可是須要安裝MATLAB提供的MATLAB Compiler Runtime,這個軟件在MATLAB的安裝目錄下:X:\MATLAB\R2010a\toolbox\compiler\deploy\win32 \MCRInstaller.exe(X是MATLAB安裝的盤符),若是你的電腦上安裝了MATLAB,則不須要在從新安裝這個軟件。另外,不一樣的 MATLAB版本提供的MATLAB Compiler Runtime可能會不一樣,若是在另外一臺電腦上本身編寫的軟件運行有問題,多是編譯器的版本不一樣引發的