最近正在給客戶作的我的項目,要求實現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