<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在做圖像處理方面的項目,需要用C#與Matlab相結合,之前是採用matlab生成dll給C#調用,但是速度比較慢,所以改爲直接調用Matlab的引擎了。</span>
本人的開發環境是Matlab2016a和VS2013,由於是調用matlab引擎,所以必須安裝Matlab。
安裝好後就可以進行開發了。
1、首先在工程中引用Matlab Application(Version 9.0)Type libaray,不同版本matlab對應的庫的版本也不一樣。
添加引用後,引用目錄下多了一個MLApp文件,如果在編程是採用MLAppClass的話還需要將該文件的屬性Embed Interop Types的True值改爲False,不然會報錯。
如果採用MLApp.MLApp則不會報錯。
例子一:直接運行Matlab語句
MLApp.MLApp matlab = null;
Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
string command;
command = "t=2:0.2:4*pi;y=sin(t);h = plot(t,y)";
String path = Directory.GetCurrentDirectory();//獲取當前路徑
matlab.Visible = 0;
matlab.Execute(command);
command = @"print(gcf, '-djpeg', '" + path + "\\Test1');close all";//保存圖片
matlab.Execute(command);
運行結果:
例子二:運行自己寫的function,名稱爲add.M。
自己寫了個function:
function [out1, out2] = add(x, y)
out1 = x+ y;
out2 = x * y;
M文件其實可以隨便放在哪裏,只要將M文件的目錄設爲工作目錄就可以(這裏的設置是在C#代碼裏設置,而不是在Matlab軟件中設置),這裏就先放在工程運行目錄下,即Debug文件夾下。
注意:如果第一次採用C#調用Matlab引擎不設置工作目錄,那麼工作目錄就是這次工程運行目錄:假設這次工程運行目錄是A,以後你所有C#調用Matlab的工作目錄都是A了,如果你下次新建了另一個工程(工程的運行目錄爲B)沒有設置工作目錄,那麼該工作目錄還是A,而不是目錄B。後面會詳細講解
C#裏調用add.M:
MLApp.MLApp matlab = null;
Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
//string path_project = Directory.GetCurrentDirectory(); //工程文件的路徑,如bin下面的debug
//string path_matlab = "cd('" + path_project + "')"; //自定義matlab工作路徑 這裏我註釋調用
//matlab.Execute(path_matlab);
//matlab.Execute("clear all");<span style="color:#ff6666;">//這條語句也很重要,先註釋掉,下面講解</span>
string command;
command = @"[a,b]=add(6,3)";
matlab.Execute(command);
try
{
var retult = matlab.GetVariable("a", "base");//獲取結果,就是傳入base字符串,而不是其他的。
var retult2 = matlab.GetVariable("b", "base");
}
catch (Exception)
{
throw;
}
當修改add.M文件爲:
function [out1, out2] = add(x, y)
out1 = x+ y+10;
out2 = x * y*10;
再次運行,運行結果如下:發現結果和預想的不一樣,
在執行函數語句直接添加下面這條語句:
matlab.Execute("clear all");
再次運行:
最大的坑——工作目錄的問題
前面的工程實現了調用add.M文件了,接下來我們再新建另一個工程,實現相減,將minus2.M文件存放在運行目錄:
function out = minus2(x, y)
out = x- y;
運行下面代碼:MLApp.MLApp matlab = null;
Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
//string path_project = Directory.GetCurrentDirectory(); //工程文件的路徑,如bin下面的debug
//string path4_matlab = "cd('" + path_project + "')"; //自定義matlab工作路徑
//matlab.Execute(path4_matlab); <span style="color:#ff0000;">這裏註釋掉了,下面會將爲什麼</span>
matlab.Execute("clear all");
string command;
command = @"a=minus2(10,4)";
//command = @"feature_crack = BridgeFeature( 'C:\Users\Administrator\Desktop\測試\',0)";
matlab.Execute(command);
try
{
var result = matlab.GetVariable("a", "base");
Console.WriteLine("result=" + result);
}
catch (Exception)
{
throw;
}
運行結果:報錯了,這是因爲這個工程的matlab工作目錄還在上一個工程(前面一個add)的matlab工程目錄下,所以就找不到minus2.M文件,此時在這個工程裏調用add.M文件也會成功,就不上圖了。解決辦法有兩種:
1、將minus2.M文件拷到上一個工程的運行目錄下。這樣肯定行,但是不好。
2、修改當前工程的matlab工作目錄(其實這裏叫註冊更好,因爲一旦添加了該目錄,該目錄就會一直在,)。
所以在C#裏面添加圖中的代碼,運行結果如下:結果就正確了!
總結:
1、C#中要進行清除變量操作,否則改變M文件裏的內容,C#運行時的結果還是原來修改之前的,
2、C#工程中要進行matlab工作路徑的添加,否則將會報錯,
3、當M文件函數的輸入時有字符串變量時,那麼在C#中寫命令語句時,該參數需要加單引號,下圖中的BridgeFeature第一次參數爲字符串類型,所以要加單引號
這幾個坑花了我好久的時間,希望給大家一個參考,少走些彎路。