標籤:
C#和MatLab的混合編程,充分利用了winform的直觀顯示和matlab的強大計算能力。在此以一個小例子的形式給大家講述一下二者混合編程的實現。
一、軟體的配置說明
C#版本:VS2010 matlab版本:matlab2013a
二、把 matlab函數編譯成dll檔案
2.1首先寫一個函數的.m檔案(如下函數MatrixOpera實現兩個矩陣的相加和相減)
%--------------------------------------------------------function [addRlt,minusRlt]=MatrixOpera(a,b)% 矩陣相加,相減[m1,n1]=size(a);[m2,n2]=size(b);if m1~=m2 || n1~=n2 display(‘矩陣大小不相同‘) error(‘參數錯誤‘);endaddRlt=a+b;minusRlt=a-b;end%-----------------------------------------------------------
2.2 建立製作的dll檔案的工程
在MatLab的命令視窗中,輸入deploytool開啟建立dll檔案的工程建立視窗,如所示
在圖中,主要分為三部分,Name:你想要命的工程名,prj是工程的尾碼;Location:建立工程的儲存位置;Type:針對c#而言,我們需要選擇.NET Assembly這一項
點擊Ok選項,工程已經建立完畢
2.3 向所建工程中添加對應的元素並編譯
上述過程中,建立了一個叫matPrj的工程(它相當於c#中的命名空間namespace);然後給它增加class(它就是c#中的類),點[add class]添加myMathClass;之後再給它添加方法(它就是函數了),點[add files],本執行個體中選中之前編寫的MatrixOpera函數。完了之後就可以編譯了,編譯需要一兩分鐘的時間,如所示
三、C#中添加matlab的dll引用
3.1開啟vs2011,建立一個表單應用程式
3.2完成dll檔案的拷貝
將matlab工程(matPrj)src檔案夾下的matPrj.dll和D:\Program Files\MATLAB\R2013a\toolbox\dotnetbuilder\bin\win64\v2.0(前邊為matlab的安裝路徑)檔案夾下的MWArray.dll拷貝到VS工程(CallMatlabDllApp)下的\bin\Debug檔案夾下
3.3在VS裡添加dll檔案的引用,然後在代碼前引用相應的命名空間
如果matlab函數複雜,還需要用到其他的空間,則視情況而定,自己憑經驗添加。
至此,已經可以利用c#調用我們用matlab編寫的函數了。
四、在C#中調用matlab提供的函數
matlab中一個m*n的矩陣對應.net中的一個1*(m*n)的數組,因此在C#中調用matlab函數的關鍵是掌握資料類型一致的一個矩陣與一個數組之間的轉換。包括以下兩個問題:
a、將C#中的參數輸入到matlab函數時,要將參數轉化為matlab的參數形式,通常是MWArray類型
b、matlab函數返回的參數,也要轉化為C#用的類型,比如數組或者數實值型別
在C#中調用本例函數的代碼如下:
matPrj.myMathClass test = new matPrj.myMathClass(); //將myMathClass類執行個體化 double[] a = { 1, 2, 3, 4, 5, 6 };//定義兩個輸入參的值 double[] b = { 1, 1, 1, 1, 1, 1 };//它們是兩個一維數組 double[,] c = new double[3, 2];//定義C#中接收輸出參數的類型 double[,] d = new double[3, 2];//是兩個二維數組 //把兩個輸入參數都轉換成中間類型,中間類型也是矩陣所以要指明維數 //這裡將兩個輸入參數轉換為兩個三行兩列的矩陣 MWNumericArray matlab_a = new MWNumericArray(3, 2, a); MWNumericArray matlab_b = new MWNumericArray(3, 2, b); //輸入參數成功轉化為一個MWArray矩陣 MWArray[] agrsIn = new MWArray[] { matlab_a, matlab_b }; //聲明輸出參數是一個MWArray矩陣兩個輸出參數,一定要寫數量 MWArray[] agrsOut = new MWArray[2]; //調用matlab函數,2表示輸入參數的個數,輸出參數前需要加 ref 關鍵字 //此例實現了兩個三行兩列的矩陣相加減 test.MatrixOpera(2, ref agrsOut, agrsIn); //把兩個輸出參數轉換成中間類型 MWNumericArray net_c = agrsOut[0] as MWNumericArray; MWNumericArray net_d = agrsOut[1] as MWNumericArray; c = (double[,])net_c.ToArray();//輸出參數成功轉化為二維數組 d = (double[,])net_d.ToArray(); //一定要注意最後c和d的轉化,不同類型的轉換差異很大厄 //ToArray()對應n*m的數組 //ToVetor()對應1維數組 //ToScalarDouble()對應單個數值 for (int i = 0 ; i <= 2; i++)//輸出結果驗證 { for (int j = 0; j <= 1; j++) { textBox1.Text += c[i, j].ToString() + " "; textBox2.Text += d[i, j].ToString() + " "; } textBox1.Text += "\r\n";//換行 textBox2.Text += "\r\n"; }
MWNumericArray是MWArray與C#等語言資料轉換中間類,實現C#與matlab函數間傳遞參數的功能
MWArray是總類型,其它的以MW開頭,以Array結尾的變數類型都可以直接對它進行賦值或取值,它是.m檔案的編譯後內部的標準類型,一切C#類型都要最終轉換成此類型,方可作為參數調用matlab函數
我在運行上述程式時,第一句將myMathClass類執行個體化報錯
但是單看這語句是沒有任何問題的
matPrj.myMathClass test = new matPrj.myMathClass();
查閱了關於錯誤的資訊,但是解決的都基本是換了一個matlab版本才解決的,偶然看見說HRESULT:0x8007000B的錯誤和編譯平台有些關係,就開始著手試試是不是因為我這平台的問題導致的,果然,換了編譯的平台就好了。
具體解決:
1:右鍵項目名稱—>屬性—>產生
2:目標平台選擇x64
再次運行程式,結果如下:
上述結果同在matlab中實現效果相同,驗證結果的正確性
脫離matlab安裝的環境下,如何?程式的運行自如:
通過com組建的形式進行混合編程,如果機器上沒有安裝MATLAB,編譯產生的軟體照樣可以使用,但是需要安裝MATLAB提供的MATLAB Compiler Runtime(MCR),這個軟體在MATLAB的安裝目錄下:X:\MATLAB\R2013a\toolbox\compiler\deploy\win32\MCRInstaller.exe(X是MATLAB安裝的盤符),如果你的電腦上安裝了MATLAB,則不需要在重新安裝這個軟體。另外,不同的MATLAB版本提供的MATLAB Compiler Runtime可能會不同,如果在另一台電腦上自己編寫的軟體運行有問題,可能是編譯器的版本不同引起的
參考資料:http://wenku.baidu.com/link?url=mgBBgQFt89s-7rKrNbJ-630AH0q_2mMMYBbvCWx9IiGkuOQ7qFTkL_pZRhT5FqazmtFoD6UUM6vWLeDrprF2OAGqUcmrHEugVntjWvzCwxy
http://www.cnblogs.com/liuxiaowei0543/p/3682377.html
http://wenku.baidu.com/view/6ad3b62b59eef8c75fbfb3ed.html
C#和matlab混合編程