您的位置:首页 > 编程语言 > MATLAB

C#调用Matlab引擎详细方法以及注意事项

2016-07-22 16:23 609 查看
<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第一次参数为字符串类型,所以要加单引号



这几个坑花了我好久的时间,希望给大家一个参考,少走些弯路。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: