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


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

一、軟件的配置說明

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

二、制作matLab的C# dll文件

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

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

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文件的工程

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

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

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

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

在上面Classes是你自己對應編寫了一個類,然后向里面添加Add files,也就是你之前編寫的M文件,經過編譯之后,就在對應的工程文件中,形成你所需要的dll文件。下一步我們如何在C#中利用對應的dll文件。

三、如何在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;

四、最后,在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可能會不同,如果在另一台電腦上自己編寫的軟件運行有問題,可能是編譯器的版本不同引起的

 


免責聲明!

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



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