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

最近在做图像处理方面的项目,需要用C#与Matlab相结合,之前是采用matlab生成dll给C#调用,但是速度比较慢,所以改为直接调用Matlab的引擎了。

本人的开发环境是Matlab2016a和VS2013,由于是调用matlab引擎,所以必须安装Matlab。

安装好后就可以进行开发了。

1、首先在工程中引用Matlab Application(Version 9.0)Type libaray,不同版本matlab对应的库的版本也不一样。

C#调用Matlab引擎详细方法以及注意事项_第1张图片

添加引用后,引用目录下多了一个MLApp文件,如果在编程是采用MLAppClass的话还需要将该文件的属性Embed Interop Types的True值改为False,不然会报错。

如果采用MLApp.MLApp则不会报错。

C#调用Matlab引擎详细方法以及注意事项_第2张图片C#调用Matlab引擎详细方法以及注意事项_第3张图片

例子一:直接运行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);

运行结果:
C#调用Matlab引擎详细方法以及注意事项_第4张图片

例子二:运行自己写的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");//这条语句也很重要,先注释掉,下面讲解
            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;
            }
C#调用Matlab引擎详细方法以及注意事项_第5张图片

当修改add.M文件为:

function [out1, out2] = add(x, y)
out1 = x+ y+10;
out2 = x * y*10;
再次运行,运行结果如下:发现结果和预想的不一样,

C#调用Matlab引擎详细方法以及注意事项_第6张图片
在执行函数语句直接添加下面这条语句:

matlab.Execute("clear all");
再次运行:

C#调用Matlab引擎详细方法以及注意事项_第7张图片

最大的坑——工作目录的问题

前面的工程实现了调用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);     这里注释掉了,下面会将为什么

            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#调用Matlab引擎详细方法以及注意事项_第8张图片


所以在C#里面添加图中的代码,运行结果如下:结果就正确了!

C#调用Matlab引擎详细方法以及注意事项_第9张图片

总结:

1、C#中要进行清除变量操作,否则改变M文件里的内容,C#运行时的结果还是原来修改之前的,

2、C#工程中要进行matlab工作路径的添加,否则将会报错,

3、当M文件函数的输入时有字符串变量时,那么在C#中写命令语句时,该参数需要加单引号,下图中的BridgeFeature第一次参数为字符串类型,所以要加单引号


这几个坑花了我好久的时间,希望给大家一个参考,少走些弯路。

你可能感兴趣的:(C#与Matlab混合编程)