在個人上一篇文章【原創】Matlab.NET混編技巧之——找出Matlab內置函數中,已經大概的介紹了matlab內置函數在混合編程中的優勢,並經過程序找出了matlab中的大部份內置函數,固然更多人關心是如何像我所說得那樣,不用直接編譯,就直接在C#中調用這些內置函數。本文就帶你揭開這些謎團。html
聲明,這篇文章是須要一點點混合編程基礎的,基本概念和過程要懂一點,若是能簡單成功混編一個簡單的計算或者繪圖例子,能夠更容易理解。web
傳統的Matlab.NET混合編程有2種方式:編程
1)Matlab編寫好M函數,利用deploytool編譯m函數生成dll,在C#項目中引用並調用;windows
2)基於接口的編寫方式,也是利用deploytool工具,過程繁瑣一點,對編程人員素質要求高一點,但不須要進行繁瑣的數據類型轉換。個人博客有一篇文章專門介紹了這個混合編程方式,也有例子,你們有興趣的能夠看看:http://www.cnblogs.com/asxinyu/archive/2013/05/16/3082299.html瀏覽器
無論上面用哪一種方式,Matlab和C#混編的基本步驟,大概都是下面的過程: app
1) 編寫M函數,並首先在Matlab中測試是正確能夠調用的。注意命名規範,註釋規範; ide
2) 使用命令打開 deploytool工具,設置項目名稱,選擇類型:.NET Assembly,而後新建一個類,並添加編寫好的M函數 函數
3) 編譯,生成dll,並在C#項目中添加引用(還須要引用對應版本的MWArray),利用對象瀏覽器查看生成dll的方法結構,並根據Matlab和C#的類型轉換規則,進行數據轉換便可, 若是是接口的編程,這個過程相對要簡單。工具
爲了好咱們今天的目的相匹配,特地封裝一個簡單的內置函數,plot,來畫一個簡單的圖形,以下所示M函數 post
1 function PlotTest(n) 2 %編寫一個簡單的函數,對plot進行簡單封裝一下 3 plot(1:n,1:n); 4 %測試正確,才能夠進行下一步工做
注意,混編必須是m函數function的形式才能被調用。上述函數簡單測試一下,沒有問題(複雜的函數必定要多測試,不然後續調試很是困難)。繼續下一步。
在Matlab工做區輸入命令:deploytool,而後獲得下面界面,輸入混編項目的名稱,選擇存儲位置,關鍵的是類型那裏必定要選擇".NET Assembly"。以下圖所示:
選擇「OK」以後,下一步matlab界面右側會出現項目解決方案,須要添加類名稱和M文件。這個類名稱,就是編譯完成以後C#項目中的類對象名稱,而後添加咱們剛纔上一步編寫的「PlotTest.m」,而後編譯便可,以下圖所示:
到此爲止,一個常規 簡單的Matlab.NET混編已經完成了60%了。編譯完成以後,打開「Package」選項卡,便可看到生成的dll文件,而後點擊右鍵,打開文件夾便可,以下圖所示:
這個過程很關鍵,其實包含不少信息,只不過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 }
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 } 147 148 149 /// <summary> 150 /// Provides a void output, 1-input Objectinterface 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(Object n) 159 { 160 mcr.EvaluateFunction(0, "PlotTest", n); 161 } 162 163 164 /// <summary> 165 /// Provides the standard 0-input Object 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 Object[] PlotTest(int numArgsOut) 176 { 177 return mcr.EvaluateFunction(numArgsOut, "PlotTest", new Object[]{}); 178 } 179 180 181 /// <summary> 182 /// Provides the standard 1-input Object 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 Object[] PlotTest(int numArgsOut, Object n) 194 { 195 return mcr.EvaluateFunction(numArgsOut, "PlotTest", n); 196 } 197 198 199 /// <summary> 200 /// Provides an interface for the PlotTest function in which the input and output 201 /// arguments are specified as an array of Objects. 202 /// </summary> 203 /// <remarks> 204 /// This method will allocate and return by reference the output argument 205 /// array.<newpara></newpara> 206 /// M-Documentation: 207 /// 編寫一個簡單的函數,對plot進行簡單封裝一下 208 /// </remarks> 209 /// <param name="numArgsOut">The number of output arguments to return</param> 210 /// <param name= "argsOut">Array of Object output arguments</param> 211 /// <param name= "argsIn">Array of Object input arguments</param> 212 /// <param name= "varArgsIn">Array of Object representing variable input 213 /// arguments</param> 214 /// 215 [MATLABSignature("PlotTest", 1, 0, 0)] 216 protected void PlotTest(int numArgsOut, ref Object[] argsOut, Object[] argsIn, params Object[] varArgsIn) 217 { 218 mcr.EvaluateFunctionForTypeSafeCall("PlotTest", numArgsOut, ref argsOut, argsIn, varArgsIn); 219 } 220 221 /// <summary> 222 /// This method will cause a MATLAB figure window to behave as a modal dialog box. 223 /// The method will not return until all the figure windows associated with this 224 /// component have been closed. 225 /// </summary> 226 /// <remarks> 227 /// An application should only call this method when required to keep the 228 /// MATLAB figure window from disappearing. Other techniques, such as calling 229 /// Console.ReadLine() from the application should be considered where 230 /// possible.</remarks> 231 /// 232 public void WaitForFiguresToDie() 233 { 234 mcr.WaitForFiguresToDie(); 235 } 236 237 238 239 #endregion Methods 240 241 #region Class Members 242 243 private static MWMCR mcr= null; 244 245 private bool disposed= false; 246 247 #endregion Class Members 248 } 249 }
對比你們就能夠發現,只不過一個更加傻瓜化,參數都是Object了,其實這樣反而很差,增長了類型轉換的代價,若是知道,爲什麼不給一個正確的給他呢。關於這2個dll的速度,曾經據說過是有差異的,博客園有人給過測試,我沒實際測試過,仍是習慣用傳統的TestDemo.cs,由於參數類型都是Object,不直觀,出了問題也有點頭疼。
後面某些類或者方法的XML註釋就不說了,自動生成的東西,能夠對照M文件的註釋來看。
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;
上面這段信息主要是說明當前Matlab編譯器的版本,由於編譯的版本和部署的MCR版本必須對應起來,不然是不能運行的。而後有編譯日期,以及編譯的參數,類名以及M函數的地址等信息,其實知道這些參數,理論上是能夠本身在程序裏面調用Matlab的編譯器進行編譯工做的,只不過比較複雜,能力有限,研究不下去。下面的引用你們應該明白,這個是MWArray.dll裏面的命名空間,因此混編的項目都要引用對應版本的MWArray.dll
1 static TestDemo() 2 { 3 if (MWMCR.MCRAppInitialized) 4 { 5 Assembly assembly= Assembly.GetExecutingAssembly(); 6 string ctfFilePath= assembly.Location; 7 int lastDelimiter= ctfFilePath.LastIndexOf(@"\"); 8 ctfFilePath= ctfFilePath.Remove(lastDelimiter, (ctfFilePath.Length - lastDelimiter)); 9 string ctfFileName = "PlotTest.ctf"; 10 Stream embeddedCtfStream = null; 11 String[] resourceStrings = assembly.GetManifestResourceNames(); 12 foreach (String name in resourceStrings) 13 { 14 if (name.Contains(ctfFileName)) 15 { 16 embeddedCtfStream = assembly.GetManifestResourceStream(name); 17 break; 18 } 19 } 20 mcr= new MWMCR("",ctfFilePath, embeddedCtfStream, true); 21 } 22 else 23 { 24 throw new ApplicationException("MWArray assembly could not be initialized"); 25 } 26 }
若是有一些C#的開發和編程經驗看上面的代碼問題應該不大,不然還真有點難說清楚,簡單的說幾個要點:
1)這個構造函數的做用主要是檢測MCR對象是否初始化,若是沒有,則尋找程序集,並拼接資源的位置,正確進行初始化
2) 上面的ctf實際上是包含在dll程序集裏面的,以資源的形式,這個文件是核心,它才真正的包括了Matlab編譯以後的,MCR能夠運行的中間程序。
3) 必需要合法正確的ctf文件和dll文件才能 正確的初始化mcr對象,合法的意思,是Matlab內部有校驗機制,包括對相關版本,在之前的版本生成文件中,很明顯,如今2012a裏面都隱藏起來了,不過要求都同樣。
4) 上面方法其實已經間接的告訴了咱們怎麼初始化mcr對象,有了mcr對象,一切都好辦了,由於它纔是MCR的核心。
1 public void PlotTest() 2 { 3 mcr.EvaluateFunction(0, "PlotTest", new MWArray[]{}); 4 } 5 public void PlotTest(MWArray n) 6 { 7 mcr.EvaluateFunction(0, "PlotTest", n); 8 } 9 public MWArray[] PlotTest(int numArgsOut) 10 { 11 return mcr.EvaluateFunction(numArgsOut, "PlotTest", new MWArray[]{}); 12 } 13 public MWArray[] PlotTest(int numArgsOut, MWArray n) 14 { 15 return mcr.EvaluateFunction(numArgsOut, "PlotTest", n); 16 }
看了字段代碼,再對應mcr的初始化,其實都很明朗了。經過mcr的EvaluateFunction來調用M函數。上面的代碼有幾個重載方法,能夠實用不少不一樣的狀況,有時候,這些方法的個數會更多,其實沒多大必要,也能夠本身編譯一下,把沒用的刪掉,保留少數幾個有用的便可。同時也能夠看到,這裏直接經過字符串來傳遞函數名稱的,所以必須保證這個函數能被mcr搜索到。好比咱們這裏的"PlotTest"這個函數其實就包含了ctf文件中(注意ctf文件是能夠和dll分開的,在混編項目裏能夠設置)。
上述已經講解了整個mcr調用的過程,其實就是經過mcr的EvaluateFunction來調用M函數,但要保證對於的函數名稱在mcr搜索的範圍內。那麼咱們是否是能夠假設:內置函數都在MCR內部,應該是能夠搜索到的,那麼把上面的函數名稱換一下,是否是也是可行的。這個假設也是我最先接觸時候的想法,有了假設,固然要去驗證。如今看來這個固然是確定的,那麼不妨從新演示一遍。過程不詳細講了,代碼也有註釋,混編要引用的MWArray.dll和命名空間也不提了,看代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Reflection; 6 using System.IO; 7 8 using MathWorks.MATLAB.NET.Utility; 9 using MathWorks.MATLAB.NET.Arrays; 10 11 12 namespace BuildInFunctionDemo 13 { 14 class Program 15 { 16 static MWMCR mcr; 17 static void Main(string[] args) 18 { 19 #region 首先使用PlotTest.dll來初始化mcr,由於這個dll是混編「合法」產生的,只有這樣才能順利啓動mcr 20 if (MWMCR.MCRAppInitialized) 21 { 22 string path = Path.Combine(System.Environment.CurrentDirectory, "PlotTest.dll"); 23 Assembly assembly = Assembly.LoadFile(path); 24 string ctfFilePath = assembly.Location; 25 int lastDelimiter = ctfFilePath.LastIndexOf(@"\"); 26 ctfFilePath = ctfFilePath.Remove(lastDelimiter, (ctfFilePath.Length - lastDelimiter)); 27 string ctfFileName = "PlotTest.ctf"; 28 Stream embeddedCtfStream = null; 29 String[] resourceStrings = assembly.GetManifestResourceNames(); 30 31 foreach (String name in resourceStrings) 32 { 33 if (name.Contains(ctfFileName)) 34 { 35 embeddedCtfStream = assembly.GetManifestResourceStream(name); 36 break; 37 } 38 } 39 mcr = new MWMCR("",ctfFilePath, embeddedCtfStream, true); 40 } 41 else 42 { 43 throw new ApplicationException("MWArray assembly could not be initialized"); 44 } 45 #endregion 46 47 #region 直接調用混編dll中的封裝函數進行測試 48 mcr.EvaluateFunction(0, "PlotTest", 5); 49 50 //注意這裏要斷點調試才能看到效果哦,由於mcr會把圖繪製在一個Figure上面, 51 //後面的會覆蓋前面的,這裏暫停一下,能夠看前面的效果 52 //下面就是直接調用matlab的plot函數的效果 53 MWNumericArray x = new double[]{1,2,3,4,5}; 54 MWNumericArray y = new double[]{2,1,2.8,5.3,4.7}; 55 mcr.EvaluateFunction(0, "plot",x,y ); 56 #endregion 57 58 Console.ReadKey(); 59 } 60 } 61 }
惟一要注意的就是50-52的說明,要加斷點看2次繪製的效果。分別截圖以下:
=
拋磚引玉,這裏只是一個思路,附代碼下載吧。