使用環境 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一類的to***x等方法還有許多,慢慢發掘吧。
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] , };
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時可能出現異常。
除錯經驗(2023年3月30日更新)
由於matlab對輸入引數的處理非常靈活,而c#在輸入輸出上十分嚴格,因此常會出現轉換資料型別出錯的問題。
解決方法是把c#介面的輸入輸出看牢:matlab函式的輸入引數最好為double型,不要double和float混雜,否則輸出可能有些是float有些是double.
關於資料介面的兩種處理方法(2023年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
Matlab與C 連線的幾種方式比較
a a.net 使用環境 visual studio 2005,matlab 2007a。前提 機器要裝好mcr 很 100mb 200mb因版本而異 否則會編譯出錯。1.com 步驟 matlab編譯工作 mbuild setup deploytool,matlab builder for net...
C 連線 Oracle 的幾種方式
一 通過system.data.oracleclient 需要安裝oracle客戶端並配置tnsnames.ora 二 通過system.data.oracleclient 需要安裝oracle客戶端不需配置tnsnames.ora 三 通過system.data.oledb和oracle公司的驅動...
C 連線 Oracle 的幾種方式
一 通過system.data.oracleclient 需要安裝oracle客戶端並配置tnsnames.ora 二 通過system.data.oracleclient 需要安裝oracle客戶端不需配置tnsnames.ora 三 通過system.data.oledb和oracle公司的驅動...