Matlab與C 連線的幾種方式比較

2021-09-07 21:34:00 字數 4299 閱讀 5862

[**:a***a.net]

使用環境 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 連線的幾種方式比較

使用環境 visual studio 2005,matlab 2007a。前提 機器要裝好mcr 很 100mb 200mb因版本而異 否則會編譯出錯。1.com 步驟 matlab編譯工作 mbuild setup deploytool,matlab builder for net,generic...

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公司的驅動...