使用環境 Visual Studio 2005,Matlab 2007a。
前提:機器要裝好MCR(很變态,100MB~200MB因版本而異),否則會編譯出錯。
1.COM
步驟:
matlab編譯工作
- mbuild -setup
- deploytool,Matlab Builder for .net,Generic COM Component
- 添加m函數檔案(eg: myfunc.m),改類名(eg: myComClass),build
注冊dll
regsvr32 myCom.dll
regsvr32 mwcomutil.dll
VS2005調用:
- Reference加Com控件
- 調用示例
double[,] arr = null;
object in_a, out_a;
in_a = 500;
out_a = arr1;
myCom.myComClass mc = new myCom.myComClass();
mc.myfunc(1, ref out_a, in_a);
注:
- 如果報錯,且報錯中有亂碼,請自己打開log看個究竟,log裡面可顯示出中文。
- VS2005必須裝上VC,否則找不到Midl這個檔案,就編譯不了com
2. .net(參見Matlab Builder for .net的幫助,有源代碼)
matlab 2006a版本之後提供此連接配接方式。
步驟:
matlab編譯工作
- mbuild -setup
- deploytool,Matlab Builder for .net,.NET Component
- 添加m函數檔案(eg: myfunc.m),改類名(eg: myClass),build
VS2005調用:
- Reference要有MWArray(%matlabpath%/toolbox/dotnetbuilder/bin/win32/v2.0)和 build出來的DLL
- 使用名空間
using MathWorks.MATLAB.NET.Utility;
using MathWorks.MATLAB.NET.Arrays;
using dll名;
- 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(和傳遞單個數值的方法一樣) //4月26日添加
double[,] dbx = new double[2, 2] { { 1, 2 }, { 3, 4 } };
MWNumericArray x=dbx;
myclass.picture(x);
其中picture是一個自己寫的m函數,内容是plot(x),用于驗證傳入的矩陣的結果。結果如下圖:

3.時間、CPU、記憶體開銷比較:
時間是這樣算得的:
DateTime tst0 = DateTime.Now;
...
DateTime tst1 = DateTime.Now;
TimeSpan dift = tst1 - tst0;
Matlab-C#記憶體/虛拟記憶體開銷(MByte)
-----------------------------------
1個magic(4) 77.9, 158.4
2個magic(4) 77.9, 158.4
1個magic(500) 84.7, 165.2
無界面程式 7.4M, 8M
時間測試(s) .NET / COM
-----------------------------------Group1
執行個體化時間 3.2813 3.2813
第一次調magic(4) 0.0469 0.0625
第二次調magic(5) 0.0000 0.0313
傳遞5x5矩陣 0.1875 未測
-----------------------------------Group2
執行個體化時間 3.2656 3.3125
第一次調magic(500) 0.1406 0.1719
第二次調magic(557) 0.0156 0.1250
傳遞500x500矩陣 0.2969 未測
-----------------------------------Group3
執行個體化時間 3.3125 未測
第一次調magic(4) 0.0469 未測
第二次調sumab(1,1) 0.0156 未測
結論:
- 開機後第一次運作程式,需要花10s左右的時間執行個體化類,之後執行個體化需要花費3s的時間。
- 耗記憶體、占時間的是将MCR執行個體化的過程!!
- 最好在程式靠前位置把封裝的類執行個體化。
- 大矩陣的類型轉換要消耗一段時間,但是和小矩陣比并不明顯。如果資料量實在很大,用檔案傳遞參數也是一個解決辦法。
- com模式和.Net模式的調用相差不大,但就編譯速度而言.net的方式要快上很多,而且似乎比較穩定。(我的機器就是如此,com編譯報錯但.net 編譯很快就通過了,而且用得不錯)
- 早期版本的MCR庫較小,估計能快一些。
- 有的機器無法編譯Com,可能是Windows XP缺乏更新檔。據說“番茄花園”等版本系統的一些服務被“優化”掉了,也不能夠正常編譯。
- 更新matlab程式,将dll複制到相應檔案夾後,應該删除檔案夾下的(dll名字)_mcr檔案夾,否則程式在載入dll時可能出現異常。
----------------------------
調試經驗(2009年3月30日更新)
由于matlab對輸入參數的處理非常靈活,而C#在輸入輸出上十分嚴格,是以常會出現轉換資料類型出錯的問題。
解決方法是把C#接口的輸入輸出看牢:Matlab函數的輸入參數最好為double型,不要double和float混雜,否則輸出可能有些是 float有些是double.
-------------------------------
關于資料接口的兩種處理方法(2009年7月22日更新)
上面的時間測試表格給出的是值傳遞方法消耗的時間。實際使用中發現傳遞參數很多時,值傳遞法需要消耗大量時間。是以又提出了通過檔案傳遞參數或結果的方法。以下是在上述兩種方法下,運算與傳回資料消耗的時間評估。
時間測試(s) 值傳遞 / 檔案
-----------------------------------Group1
執行個體化時間 3.5625 3.5937
第一次調magic(4) 0.0469 0.0781
第二次調magic(500) 0.1250 0.1406
傳遞500x500矩陣 0.2812 0.0000(無法測出)
由于檔案傳遞500x500的整形矩陣時間太短無法測出,故改為800x800以評估其時間。消耗時間為:0.0156
原帖: http://hi.baidu.com/adda/blog/item/c19bd33f3d87a6c77d1e714f.html