天天看點

Matlab與C#連接配接的幾種方式比較

使用環境 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),用于驗證傳入的矩陣的結果。結果如下圖:

Matlab與C#連接配接的幾種方式比較

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

繼續閱讀