C#和MatLab的混合編程(充分利用兩者的優點)

C#和MatLab的混合編程,充分利用了winform的直觀顯示和matlab的強大計算能力。在此以一個小例子的形式給你們講述一下兩者混合編程的實現。編程

1、軟件的配置說明c#

C#版本:VS2010;MatLab版本:MatLab2011a數組

2、製做matLab的C# dll文件ide

2.1首先寫一個M文件(實現你想要的函數執行形式)函數

以網上down了一個M文件(實現基本的繪圖功能),內容見下表,ui

function test(h,D)
for x=-10:0.1:10,
   if x>D
       y=h;
       hold on;
       plot(x,y)
   elseif x<-D
       y=-h;  
       hold on;
       plot(x,y)
   else
       y=h/(D*x);
       hold on;
       plot(x,y)
   end
end

 2.2 建立製做的dll文件的工程spa

在MatLab的命令窗口中,輸入deploytool,或者利用菜單選項,file-new-deployment project打開建立dll文件的工程建立窗口,以下圖所示。.net

在圖中,主要分爲如下三部分,Name:你想要命名的名字,prj是工程的後綴(通常不忽略);location:建立工程的儲存位置;type:針對c#而言,咱們須要選擇.net assembly這一項;點擊Ok選項,工程已經建立完畢。下一步就是向工程中加入你想要的方法等元素。debug

2.3 向所建工程中添加對應的元素3d

上述過程當中,就至關於在C#中建立了Untitled2的命名空間,須要在此添加對應的類和方法。基於上述的例子,下一步,咱們在窗體菜單中  destop-.netAssembly-點擊選擇,見下圖所示。

在上面Classes是你本身對應編寫了一個類,而後向裏面添加Add files,也就是你以前編寫的M文件,通過編譯以後,就在對應的工程文件中,造成你所須要的dll文件。下一步咱們如何在C#中利用對應的dll文件。

3、如何在C#中利用Matlab製做的dll文件

3.1首先,將matlab中對應的剛編寫好的untitled的dll文件,同時從C:\Programs\Files\MatLab\R2011a\toolbox\dotnetbuilder\bin\win64\v2.0中拷貝出MWArrary.dll和ManagedCPPAPI.netModule三個文件拷貝到C#編寫的工程文件中去,C#編程文件的debug文件中。在這裏特別說明的一點是:最後一個文件在matlab2011a中沒有找到對應的文件,發現並不影響程序的執行。

3.2在C#的工程中,咱們在引用中----添加對彼此dll文件的引用。見下圖

3.3命名空間的引用 using.....的書寫

using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using Untitled1;

4、最後,在C#中如何引用這些matlab提供的計算模塊的功能實現

 4.1 在C#中調用MatLab的函數是最重要的是函數變量之間的傳遞是如何實現的?

包括如下幾個問題:a、將C#的參數帶入到matLab的函數的參數中,將C#的參數轉化成對應的MWArray類型。

                          b、如何將Matlab函數返回的類型,轉化成C#對應的函數類型。

 4.2 MWNumericArray是MWArray和c#中數據的中間類,實現C#與matlab間傳遞參數的功能

 

a.double型、int型等數值類型的變量傳遞

MWNumericArray i = null, result = mydouble;

i=4;

myClass myclass = new myClass(); //實例化

result = (MWNumericArray)myclass.myfunc(i);

b.字符串(須要用到MWCharArray和MWArray轉換)

MWCharArray FileName = myString;

MWNumericArray sensitivity;

sensitivity = (MWNumericArray)myClass.myAlgorithm((MWArray)FileName);

c.多個輸出參數組成的數組

MWNumericArray out_Arr = (MWNumericArray)out_Args[1]; //取出第一個參數返回的數組(matlab返回的數組下界是從1開始的)

取出數組中的一個元素值

mydouble=out_Arr[i].ToScalarDouble();

如上面例子ToScalarDouble一類的toXXXX等方法還有許多。

d.result.toArray能夠把matlab返回的矩陣變成C#的n x m數組,eg:

double[,] csArray= (double[,])result.ToArray(MWArrayComponent.Real);

e.將數組傳入Matlab(和傳遞單個數值的方法同樣)

double[,] dbx = new double[2, 2] { { 1, 2 }, { 3, 4 } };

MWNumericArray x=dbx;

myclass.picture(x);

 

testz.testzclass st = new testz.testzclass();

             MWArray[] max = st.testz(2);

             MWNumericArray x1 = (MWNumericArray)max[0];

             MWNumericArray x2 = (MWNumericArray)max[1];

             double[,] location1 = (double[,])x1.ToArray(MWArrayComponent.Real);

             double[,] location2 = (double[,])x2.ToArray(MWArrayComponent.Real);

             label1.Text = location1[1,2].ToString();

其中的M文件:

Code

function [x1,x2]=testz()

x1=[1 2 3;

    4 5 6;

    7 8 9;];

x2=[9 8 7;

    6 5 4;

    3 2 1;]

 

經常使用的轉換函數:      

① public Array ToArray(MWArrayComponent component);

將M類型轉換成C#的Array類型,而後能夠直接轉換成其它類型的數組。

② public byte ToScalarByte();

將M類型轉換成C#的字節類型;

③ public double ToScalarDouble();

將M類型轉換成C#的雙精度類型;

double temp = ((MWNumericArray)(mwArgout[0])).ToScalarDouble();

④ public float ToScalarFloat();

將M類型轉換成C#的單精度類型;

⑤ public int ToScalarInteger();

將M類型轉換成C#的整型類型;

⑥ public long ToScalarLong();

將M類型轉換成C#的長整C/C++/C#數據型類型;

⑦ public short ToScalarShort();

將M類型轉換成C#的短整型類型;

⑧  public override string ToString();

將M類型轉換成C#的字符串類型;string arror = mwArgout[2].ToString();

⑨  public Array ToVector(MWArrayComponent component);

將M類型轉換成C#的Array類型,而後能夠直接轉換成其它類型的數組。

下面使用調試過的代碼示例表述①⑨兩個函數的區別:

double[,] Temp1 = new double[1,3];           

Temp1= (double[,])((MWNumericArray)mwArgout[1]).ToArray(MWArrayComponent.Real);

double[] s1 = new double[2];                

s1 = (double[])((MWNumericArray)mwArgout[1]).ToVector(MWArrayComponent.Real);

從以上代碼能夠看出:函數①獲得了二維數組,而⑨則是獲得了一維數組。轉換成C++/C#數據類型後,它們的維數均爲從0開始。

 

 最後總結:

C++/C#數據類型到M類型

此方向轉換十分簡單。

若是C++/C#數據不是數組,

直接將值傳遞給已經初始化的MWArray數組中的成員

直接將數據類型賦值給已經初始化的MWNumericArray變量。

直接將字符串類賦值給已經初始化的MWCharArray變量。 

     若是是數組類型:

直接賦值給MWNumericArray變量;

賦值給MWArray變量,則在前面加上類型轉換如:(MWNumericArray)進行強制轉換。

總之,MWArray是總類型,其它的以MW開頭,以Array結尾的變量類型均可以直接對它進行賦值或取值。

M類型到C++/C#數據類型

MWArray

M類型,它是M文件的編譯後內部的標準類型,一切C++/C#類型都要最終轉換成此類型,方可做爲參數調用M語言函數。

MWCharArray

M的字符串類型,使用它能夠將M中的字符類型轉換成C++/C#的字符串類型。

MWNumericArray

MWNumericArray是MWArray與C#等語言的轉換中間類型。

 上述整理參考了文獻出自http://zxfcool2000.blog.163.com/blog/static/31852320101117111555598/

在實現過程當中遇到的問題:

錯誤信息:「未能加載文件或程序集「MWArray, Version=2.11.1.0, Culture=neutral, PublicKeyToken=e1d84a0da19db86f」或它的某一個依賴項。試圖加載格式不正確的程序。」

解決方案:將C#項目屬性從x86->x64就好了

補充一個例子的應用:

M文件:

function [x1,x2]=test(x3)
x1=[1 x3*x3 x3;
    1-x3 5 6;
    7 8 9;];
x2=[9 8 7;
    6 5 4;
    3 2 1;];

 在C#中造成的幾種函數形式以下:

        public MWArray test();
        public MWArray[] test(int numArgsOut);
        public MWArray test(MWArray x3);
        public MWArray[] test(int numArgsOut, MWArray x3);
        public void test(int numArgsOut, ref MWArray[] argsOut, MWArray[] argsIn);

因此在C#中能夠選擇不一樣的形式調用,其中numArgsOut指的是輸出參數的個數  argsOut:輸出參數,固然儘管C#中泛泛提出了幾種函數形式,確只有第3,4,5是可使用的(結合本身寫的M文件內容)

脫離matlab安裝的環境下,如何實現程序的運行自如: 

經過com組建的形式進行混合編程,若是機器上沒有安裝MATLAB,編譯生成的軟件照樣可使用,可是須要安裝MATLAB提供的MATLAB Compiler Runtime,這個軟件在MATLAB的安裝目錄下:X:\MATLAB\R2010a\toolbox\compiler\deploy\win32 \MCRInstaller.exe(X是MATLAB安裝的盤符),若是你的電腦上安裝了MATLAB,則不須要在從新安裝這個軟件。另外,不一樣的  MATLAB版本提供的MATLAB Compiler Runtime可能會不一樣,若是在另外一臺電腦上本身編寫的軟件運行有問題,多是編譯器的版本不一樣引發的

相關文章
相關標籤/搜索