• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

              本博客所有文章分类的总目录:【总目录】本博客博文总目录-实时更新

      Matlab和C#混合编程文章目录 :【目录】Matlab和C#混合编程文章目录

  在我的上一篇文章【原创】Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了matlab内置函数在混合编程中的优点,并通过程序找出了matlab中的大部分内置函数,当然更多人关心是如何像我所说得那样,不用直接编译,就直接在C#中调用这些内置函数。本文就带你揭开这些谜团。

声明,这篇文章是需要一点点混合编程基础的,基本概念和过程要懂一点,如果能简单成功混编一个简单的计算或者绘图例子,可以更容易理解。

1.传统的Matlab.NET混合编程步骤

传统的Matlab.NET混合编程有2种方式:

1)Matlab编写好M函数,利用deploytool编译m函数生成dll,在C#项目中引用并调用;

2)基于接口的编写方式,也是利用deploytool工具,过程繁琐一点,对编程人员素质要求高一点,但不需要进行繁琐的数据类型转换。我的博客有一篇文章专门介绍了这个混合编程方式,也有例子,大家有兴趣的可以看看:http://www.cnblogs.com/asxinyu/archive/2013/05/16/3082299.html

 不管上面用哪种方式,Matlab和C#混编的基本步骤,大概都是下面的过程: 

1) 编写M函数,并首先在Matlab中测试是正确可以调用的。注意命名规范,注释规范; 

2) 使用命令打开 deploytool工具,设置项目名称,选择类型:.NET Assembly,然后新建一个类,并添加编写好的M函数 

3) 编译,生成dll,并在C#项目中添加引用(还需要引用对应版本的MWArray),利用对象浏览器查看生成dll的方法结构,并根据Matlab和C#的类型转换规则,进行数据转换即可, 如果是接口的编程,这个过程相对要简单。

2.深入解析传统混编所生成的代码

2.1 第一步:编写M函数,并测试可以使用

为了好我们今天的目的相匹配,特意封装一个简单的内置函数,plot,来画一个简单的图形,如下所示M函数    

1 function PlotTest(n)
2 %编写一个简单的函数,对plot进行简单封装一下
3 plot(1:n,1:n);
4 %测试正确,才可以进行下一步工作

注意,混编必须是m函数function的形式才能被调用。上述函数简单测试一下,没有问题(复杂的函数一定要多测试,否则后续调试非常困难)。继续下一步。

2.2 第二步:在Matlab中使用deploytool建立混编项目

 在Matlab工作区输入命令:deploytool,然后得到下面界面,输入混编项目的名称,选择存储位置,关键的是类型那里一定要选择".NET Assembly"。如下图所示:

选择“OK”之后,下一步matlab界面右侧会出现项目解决方案,需要添加类名称和M文件。这个类名称,就是编译完成之后C#项目中的类对象名称,然后添加我们刚才上一步编写的“PlotTest.m”,然后编译即可,如下图所示:

到此为止,一个常规 简单的Matlab.NET混编已经完成了60%了。编译完成之后,打开“Package”选项卡,即可看到生成的dll文件,然后点击右键,打开文件夹即可,如下图所示:

2.3 查看混编生成的代码

  这个过程很关键,其实包含很多信息,只不过95%以上的人都没有注意到其实混编生成的dll是有源文件的,通过查看源文件就应该知道混编的原理,只不过这是matlab自动生成 而已。那看看生成的源码吧。

  打开Matlab混编项目的目录,可以看到有2个文件夹,"distrib”,“src”2个文件夹。"distrib"文件夹就是上面图中生成的dll,注意有2个dll,1个是“项目名称.dll”,一个是“项目名称Native.dll”,这2个dll的差别可以通过"distrib"文件夹源码来观察。“distrib”就是源代码的文件夹。如下图所示,src文件夹的文件示意图:

 我们2.2中新建的类名是TestDemo,所以生成的的源码名称也是TestDemo,看看这2个cs文件中的代码,同时类的方法也可以在VS中通过对象浏览器来查看dll有哪些方法以及方法的参数类型。直接贴这2个cs文件的代码,顺便解释和对比下:

TestDemo.cs文件源码:

  1 /*
  2 * MATLAB Compiler: 4.17 (R2012a)
  3 * Date: Mon Sep 09 16:19:01 2013
  4 * Arguments: "-B" "macro_default" "-W" "dotnet:PlotTest,TestDemo,0.0,private" "-T"
  5 * "link:lib" "-d" "D:\Work\DevelopMent_SVN\Matlab\MatlabBlog\PlotTest\src" "-w"
  6 * "enable:specified_file_mismatch" "-w" "enable:repeated_file" "-w"
  7 * "enable:switch_ignored" "-w" "enable:missing_lib_sentinel" "-w" "enable:demo_license"
  8 * "-v" "class{TestDemo:D:\Work\DevelopMent_SVN\Matlab\MatlabBlog\PlotTest.m}" 
  9 */
 10 using System;
 11 using System.Reflection;
 12 using System.IO;
 13 using MathWorks.MATLAB.NET.Arrays;
 14 using MathWorks.MATLAB.NET.Utility;
 15 
 16 #if SHARED
 17 [assembly: System.Reflection.AssemblyKeyFile(@"")]
 18 #endif
 19 
 20 namespace PlotTest
 21 {
 22 
 23   /// <summary>
 24   /// The TestDemo class provides a CLS compliant, MWArray interface to the M-functions
 25   /// contained in the files:
 26   /// <newpara></newpara>
 27   /// D:\Work\DevelopMent_SVN\Matlab\MatlabBlog\PlotTest.m
 28   /// <newpara></newpara>
 29   /// deployprint.m
 30   /// <newpara></newpara>
 31   /// printdlg.m
 32   /// </summary>
 33   /// <remarks>
 34   /// @Version 0.0
 35   /// </remarks>
 36   public class TestDemo : IDisposable
 37   {
 38     #region Constructors
 39 
 40     /// <summary internal= "true">
 41     /// The static constructor instantiates and initializes the MATLAB Compiler Runtime
 42     /// instance.
 43     /// </summary>
 44     static TestDemo()
 45     {
 46       if (MWMCR.MCRAppInitialized)
 47       {
 48         Assembly assembly= Assembly.GetExecutingAssembly();
 49 
 50         string ctfFilePath= assembly.Location;
 51 
 52         int lastDelimiter= ctfFilePath.LastIndexOf(@"\");
 53 
 54         ctfFilePath= ctfFilePath.Remove(lastDelimiter, (ctfFilePath.Length - lastDelimiter));
 55 
 56         string ctfFileName = "PlotTest.ctf";
 57 
 58         Stream embeddedCtfStream = null;
 59 
 60         String[] resourceStrings = assembly.GetManifestResourceNames();
 61 
 62         foreach (String name in resourceStrings)
 63         {
 64           if (name.Contains(ctfFileName))
 65           {
 66             embeddedCtfStream = assembly.GetManifestResourceStream(name);
 67             break;
 68           }
 69         }
 70         mcr= new MWMCR("",
 71                        ctfFilePath, embeddedCtfStream, true);
 72       }
 73       else
 74       {
 75         throw new ApplicationException("MWArray assembly could not be initialized");
 76       }
 77     }
 78 
 79 
 80     /// <summary>
 81     /// Constructs a new instance of the TestDemo class.
 82     /// </summary>
 83     public TestDemo()
 84     {
 85     }
 86 
 87 
 88     #endregion Constructors
 89 
 90     #region Finalize
 91 
 92     /// <summary internal= "true">
 93     /// Class destructor called by the CLR garbage collector.
 94     /// </summary>
 95     ~TestDemo()
 96     {
 97       Dispose(false);
 98     }
 99 
100 
101     /// <summary>
102     /// Frees the native resources associated with this object
103     /// </summary>
104     public void Dispose()
105     {
106       Dispose(true);
107 
108       GC.SuppressFinalize(this);
109     }
110 
111 
112     /// <summary internal= "true">
113     /// Internal dispose function
114     /// </summary>
115     protected virtual void Dispose(bool disposing)
116     {
117       if (!disposed)
118       {
119         disposed= true;
120 
121         if (disposing)
122         {
123           // Free managed resources;
124         }
125 
126         // Free native resources
127       }
128     }
129 
130 
131     #endregion Finalize
132 
133     #region Methods
134 
135     /// <summary>
136     /// Provides a void output, 0-input MWArrayinterface to the PlotTest M-function.
137     /// </summary>
138     /// <remarks>
139     /// M-Documentation:
140     /// 编写一个简单的函数,对plot进行简单封装一下
141     /// </remarks>
142     ///
143     public void PlotTest()
144     {
145       mcr.EvaluateFunction(0, "PlotTest", new MWArray[]{});
146     }
147 
148 
149     /// <summary>
150     /// Provides a void output, 1-input MWArrayinterface to the PlotTest M-function.
151     /// </summary>
152     /// <remarks>
153     /// M-Documentation:
154     /// 编写一个简单的函数,对plot进行简单封装一下
155     /// </remarks>
156     /// <param name="n">Input argument #1</param>
157     ///
158     public void PlotTest(MWArray n)
159     {
160       mcr.EvaluateFunction(0, "PlotTest", n);
161     }
162 
163 
164     /// <summary>
165     /// Provides the standard 0-input MWArray interface to the PlotTest M-function.
166     /// </summary>
167     /// <remarks>
168     /// M-Documentation:
169     /// 编写一个简单的函数,对plot进行简单封装一下
170     /// </remarks>
171     /// <param name="numArgsOut">The number of output arguments to return.</param>
172     /// <returns>An Array of length "numArgsOut" containing the output
173     /// arguments.</returns>
174     ///
175     public MWArray[] PlotTest(int numArgsOut)
176     {
177       return mcr.EvaluateFunction(numArgsOut, "PlotTest", new MWArray[]{});
178     }
179 
180 
181     /// <summary>
182     /// Provides the standard 1-input MWArray interface to the PlotTest M-function.
183     /// </summary>
184     /// <remarks>
185     /// M-Documentation:
186     /// 编写一个简单的函数,对plot进行简单封装一下
187     /// </remarks>
188     /// <param name="numArgsOut">The number of output arguments to return.</param>
189     /// <param name="n">Input argument #1</param>
190     /// <returns>An Array of length "numArgsOut" containing the output
191     /// arguments.</returns>
192     ///
193     public MWArray[] PlotTest(int numArgsOut, MWArray n)
194     {
195       return mcr.EvaluateFunction(numArgsOut, "PlotTest", n);
196     }
197 
198 
199 
200     /// <summary>
201     /// This method will cause a MATLAB figure window to behave as a modal dialog box.
202     /// The method will not return until all the figure windows associated with this
203     /// component have been closed.
204     /// </summary>
205     /// <remarks>
206     /// An application should only call this method when required to keep the
207     /// MATLAB figure window from disappearing.  Other techniques, such as calling
208     /// Console.ReadLine() from the application should be considered where
209     /// possible.</remarks>
210     ///
211     public void WaitForFiguresToDie()
212     {
213       mcr.WaitForFiguresToDie();
214     }
215 
216 
217 
218     #endregion Methods
219 
220     #region Class Members
221 
222     private static MWMCR mcr= null;
223 
224     private bool disposed= false;
225 
226     #endregion Class Members
227   }
228 }
View Code

TestDemoNative.cs文件源码:

  1 /*
  2 * MATLAB Compiler: 4.17 (R2012a)
  3 * Date: Mon Sep 09 16:19:01 2013
  4 * Arguments: "-B" "macro_default" "-W" "dotnet:PlotTest,TestDemo,0.0,private" "-T"
  5 * "link:lib" "-d" "D:\Work\DevelopMent_SVN\Matlab\MatlabBlog\PlotTest\src" "-w"
  6 * "enable:specified_file_mismatch" "-w" "enable:repeated_file" "-w"
  7 * "enable:switch_ignored" "-w" "enable:missing_lib_sentinel" "-w" "enable:demo_license"
  8 * "-v" "class{TestDemo:D:\Work\DevelopMent_SVN\Matlab\MatlabBlog\PlotTest.m}" 
  9 */
 10 using System;
 11 using System.Reflection;
 12 using System.IO;
 13 using MathWorks.MATLAB.NET.Arrays;
 14 using MathWorks.MATLAB.NET.Utility;
 15 
 16 #if SHARED
 17 [assembly: System.Reflection.AssemblyKeyFile(@"")]
 18 #endif
 19 
 20 namespace PlotTestNative
 21 {
 22 
 23   /// <summary>
 24   /// The TestDemo class provides a CLS compliant, Object (native) interface to the
 25   /// M-functions contained in the files:
 26   /// <newpara></newpara>
 27   /// D:\Work\DevelopMent_SVN\Matlab\MatlabBlog\PlotTest.m
 28   /// <newpara></newpara>
 29   /// deployprint.m
 30   /// <newpara></newpara>
 31   /// printdlg.m
 32   /// </summary>
 33   /// <remarks>
 34   /// @Version 0.0
 35   /// </remarks>
 36   public class TestDemo : IDisposable
 37   {
 38     #region Constructors
 39 
 40     /// <summary internal= "true">
 41     /// The static constructor instantiates and initializes the MATLAB Compiler Runtime
 42     /// instance.
 43     /// </summary>
 44     static TestDemo()
 45     {
 46       if (MWMCR.MCRAppInitialized)
 47       {
 48         Assembly assembly= Assembly.GetExecutingAssembly();
 49 
 50         string ctfFilePath= assembly.Location;
 51 
 52         int lastDelimiter= ctfFilePath.LastIndexOf(@"\");
 53 
 54         ctfFilePath= ctfFilePath.Remove(lastDelimiter, (ctfFilePath.Length - lastDelimiter));
 55 
 56         string ctfFileName = "PlotTest.ctf";
 57 
 58         Stream embeddedCtfStream = null;
 59 
 60         String[] resourceStrings = assembly.GetManifestResourceNames();
 61 
 62         foreach (String name in resourceStrings)
 63         {
 64           if (name.Contains(ctfFileName))
 65           {
 66             embeddedCtfStream = assembly.GetManifestResourceStream(name);
 67             break;
 68           }
 69         }
 70         mcr= new MWMCR("",
 71                        ctfFilePath, embeddedCtfStream, true);
 72       }
 73       else
 74       {
 75         throw new ApplicationException("MWArray assembly could not be initialized");
 76       }
 77     }
 78 
 79 
 80     /// <summary>
 81     /// Constructs a new instance of the TestDemo class.
 82     /// </summary>
 83     public TestDemo()
 84     {
 85     }
 86 
 87 
 88     #endregion Constructors
 89 
 90     #region Finalize
 91 
 92     /// <summary internal= "true">
 93     /// Class destructor called by the CLR garbage collector.
 94     /// </summary>
 95     ~TestDemo()
 96     {
 97       Dispose(false);
 98     }
 99 
100 
101     /// <summary>
102     /// Frees the native resources associated with this object
103     /// </summary>
104     public void Dispose()
105     {
106       Dispose(true);
107 
108       GC.SuppressFinalize(this);
109     }
110 
111 
112     /// <summary internal= "true">
113     /// Internal dispose function
114     /// </summary>
115     protected virtual void Dispose(bool disposing)
116     {
117       if (!disposed)
118       {
119         disposed= true;
120 
121         if (disposing)
122         {
123           // Free managed resources;
124         }
125 
126         // Free native resources
127       }
128     }
129 
130 
131     #endregion Finalize
132 
133     #region Methods
134 
135     /// <summary>
136     /// Provides a void output, 0-input Objectinterface to the PlotTest M-function.
137     /// </summary>
138     /// <remarks>
139     /// M-Documentation:
140     /// 编写一个简单的函数,对plot进行简单封装一下
141     /// </remarks>
142     ///
143     public void PlotTest()
144     {
145       mcr.EvaluateFunction(0, "PlotTest", new Object[]{});
146     }

                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
用Delphi改变图片的像素,即大小发布时间:2022-07-18
下一篇:
Delphi-使用字符串时,一个注意地方发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap