【原創】Matlab與.NET基於類型安全的接口混合編程入門


              本博客所有文章分類的總目錄:http://www.cnblogs.com/asxinyu/p/4288836.html

      Matlab和C#混合編程文章目錄 :http://www.cnblogs.com/asxinyu/p/4329753.html

如果這些文章對你有用,有幫助,期待更多開源組件介紹,請不要吝嗇手中的鼠標。 

 
關鍵詞:Matlab混合編程,C#調用Matlab,Matlab與C#混編,MCR,Type-Safe Interfaces

時間:2013年4月21日,5月5日例子Demo測試成功

1.前言

Matlab Builder NE 工具箱是與C#混編的工具箱,里面的幫助文檔很詳細,提供了4種情況下與.NET混合編程的案例。

1.是簡單的組件集成,通過Matlab生成Dll程序集,在.NET環境中,通過MWArray組件來調用;

2.還有一個是在Web環境下使用Figure和混編的情況,與1比較類似;

3.另外一個就是我們今天要講到的基於類型安全的接口編程,以及對WCF和MEF的支持;

4.最后一個是在.NET Remoting技術中的使用。

在初級入門教程中,以及我現在的混編開發中,都只是用到了第1個方法,和很簡單,也很快,當然要你掌握了很多基礎技術之后才能達到這個水平。今天要見到的基於接口的編程,有一個很大的好處就是可以避免類型轉換,因為之前的方法都有大量的.NET和Matlab類型進行轉換,基礎不扎實的朋友很容易搞混淆。而基於接口的編程,則可以避免很多問題,但同時也對基礎提出了更高的要求,要對接口定義,作用,以及方法多態等面向對象的特性更加了解。

下面截圖是在Matlab幫助的說明:

2.Type-Safe Interfaces簡單說明

與直接編譯為.NET程序集的要求不同,使用這項技術對.NET程序員的要求小很多,只需要很少的Matlab知識,但要對.NET技術精通,

之前由於Matlab的數據類型和.NET的基本數據類型不兼容,所以為了使得Matlab.NET程序進行數據通信,就需要使用下面的技術:

1)Marshal data from .NET input data to a deployed function by creating an MWArray object from native .NET data. 

The public functions in a deployed component return MWArray objects. 

2)Marshal the output MATLAB data in an MWArray into native .NET data by calling one of the MWArray marshaling methods (ToArray(), for example).

所以使用傳統的混編方式,又很多數據類型轉換的過程。而在使用Type-Safe Interfaces技術后,這些中間過程都可以忽略,

只需要關系輸入的.NET類型以及輸出的.NET類型結果,Matlab會對數據進行內部的轉換處理。可以看看前后2副圖的對比:

 

因此,我們可以很明顯的看到Type-Safe Interfaces帶來的優勢:

You avoid training and coding costs associated with teaching end users to work with MWArrays.

You minimize cost of data you must marshal by either placing MWArray objects in type-safe interfaces or by calling MWArray-based functions in the deployed component. 

Flexibility — you mix type-safe interfaces with manual data marshaling to accommodate data of varying sizes and access patterns. 

For example, you may have a few large data objects (images, for example) that would incur excess cost to your organization if managed

 with a type-safe interface. By mixing type-safe interfaces and manual marshaling, smaller data types can be managed 

automatically with the type-safe interface and your large data can be managed on an as-needed basis.

3.Type-Safe Interfaces實際案例

對這個混編方式,很顯示可以節省很多事情,我認為,作為原始的數據類型轉換方式,還是應該掌握的。在掌握了之后,再使用這個方法,會事半功倍,畢竟不是所有的問題都可以用接口解決。接下來,就讓我們一起用一個小的編程實例,來演示整個過程的使用。

演示環境:Visual Studio 2010,Matlab 2012a,.NET 4.0

演示內容:一個簡單的乘法運算混編實現

一、新建一個 類庫類型的項目 ,名稱MatlabDemo,.NET 4.0,如下圖所示:

一、在上面的項目中添加一個接口文件IMultiply.cs,並編寫下面的代碼,因為我們實現的是一個簡單的乘法,所以添加如下幾個接口方法:

 1 namespace MatlabDemo 
 2  { 
 3      /// <summary>乘法接口</summary> 
 4      public interface IMultiply 
 5      { 
 6          //2個數直接相乘 
 7         double multiply(double x, double y);
 8  
 9          //數組相乘 
10        double[] multiply(double[] x, double y);
11  
12          //矩陣相乘 
13        double[,] multiply(double[,] x, double[,] y); 
14      } 
15  }

  這里注意,一定要將接口的可訪問性設置為Public,否則混編的時候,Matlab會找不到接口原型,編譯失敗。編寫好,編譯項目即可,會在bin文件夾下得到MatlabDemo.dll文件,這個文件下面的步驟會用到。

三、編寫M函數,並設置混編項目。我們編寫一個簡單的乘法M函數m,如下所示:

1 function z = multiply(x, y)
2 
3     z = x * y;

注意這里的名稱一定要和接口方法的名稱對於起來,否則Matlab怎么會認識,想想就明白了。然后在Matlab中輸入deploytool命令,輸入項目名稱:TypeSaftDemo,並選擇項目類型:.NET Assembly,這個過程是“混編三部曲”基本過程,以前的視頻中專門見到了,不仔細說明,如下圖所示:

確定之后,混編項目基本就建立了,然后新建一個類DemoTest,並把上面編寫的multiply.m函數添加到這個類中去,這其實就是一個常規的混編過程,很簡單。添加完成之后,如果是普通的混編方式,直接編譯就可以了,但基於接口的混編方式,還有一個過程要設置,看下圖,單擊混編項目的設置(Settings...):

如下圖,打開設置后,選擇“Type Safe API”選項卡:

首先,選擇我們在第一個過程中編寫好的MatlabDemo.dll接口文件,選擇后,程序會自動搜索該dll中的可用接口(公開的),在.NET interface下拉列表中顯示,選擇你需要的,這里我們是IMultiply,如下圖所示的MatlabDemo.IMultiply,然后選擇該接口和Matlab混編程序中對於的類,我們的multiply.m函數在DemoTest類中,如下圖的Wrapped class:

 設置完成之后,關閉即可。然后編譯,如果沒有問題,提示編譯成功之后,打開編譯好的文件夾,我們可以看到如下3個dll文件:

生成的3個文件,TypeSafeDemo.dll其實和普通的混編方式是一樣的,可以和以前數據類型轉換的方式一樣使用;而DemoTestIMultiply.dll和TypeSafeDemoNative.dll這2個一起使用,Matlab已經在內部將數據轉換過程封裝好了,直接使用即可。第一種方式就不演示了,直接演示如何用接口來計算乘法。

五、C#調用混編好的dll計算結果。在上一節中我們已經說明了幾個dll的作用,下面將演示他們的用法,將DemoTestIMultiply.dll和TypeSafeDemoNative.dll一起復制到測試項目的C#項目中去(新建一個控制台測試項目),分別添加這幾個dll的引用:MWAarray.dll和DemoTestIMultiply.dll以及TypeSafeDemoNative.dll。然后添加命名空間,具體核心代碼如下所示:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 using MathWorks.MATLAB.NET.Arrays;
 7 using MathWorks.MATLAB.NET.Utility;
 8 
 9 using TypeSaftDemo;
10 
11 namespace TypeSaftTest
12 {
13     class Program
14     {
15         static void Main(string[] args)
16         {
17             //混編接口類的實例化
18             DemoTestIMultiply di = new DemoTestIMultiply();
19             double[,] a = new double[2,2] {{1,2},{3,4} };
20             double[,] b = new double[2, 2] { { 6, 7 }, {8, 9 } };
21             //分別演示接口的3種不同調用
22             var t1 = di.multiply(3, 5);
23             var t2 = di.multiply(new double[] { 1, 2, 3 }, 5);
24             var t3 = di.multiply(a, b);
25             Console.WriteLine("2個數直接相乘:"+t1.ToString());
26             Console.Write("數組與單個數直接相乘:");
27             foreach (var item in t2 ) Console.Write(item.ToString()+"   ");
28             Console.WriteLine();
29             Console.Write("矩陣乘法:");
30             foreach (var item in t3) Console.Write(item.ToString() + "   ");
31             Console.ReadKey ();
32         }
33     }
34 }

結果如下圖所示:

   上面就是Matlab和C#基於接口的混合編程的詳細過程,混編是一個很有用的工具,但要用好,其實真的很難,接觸混編這么長的時間以來,碰到過很多同學使用這個工具,絕大部分是誤用,導致無故的工作量。要想混編成為自己工作和學習的得力助手,必須加強Matlab和.NET基礎的學習,只有2者的基礎掌握好了,足夠熟悉這2個平台,你才可能更順利的解決混編過程中遇到的問題。當混編出了問題的時候,需要很多經驗才能度過難關,這一點很重要,不要指望學會這個過程,就可以解決所有問題。期待Mathworks公司對Matlab的混編編程支持越來越強大。

4.相關資源

1 Matlab Builder NE具箱的User’s Guide欄目中的Type-Safe Interfaces, WCF, and MEF

2 Loren Shure 博客:

 http://blogs.mathworks.com/loren/2011/06/03/introducing-type-safe-apis-with-builder-ne/

 http://blogs.mathworks.com/loren/2011/06/30/multiple-inputs-and-outputs-in-builder-ne-type-safe-apis/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM