• 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:ProgramsFilesMatLabR2011a oolboxdotnetbuilderinwin64v2.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:MATLABR2010a oolboxcompilerdeploywin32 MCRInstaller.exe(X是MATLAB安装的盘符),如果你的电脑上安装了MATLAB,则不需要在重新安装这个软件。另外,不同的  MATLAB版本提供的MATLAB Compiler Runtime可能会不同,如果在另一台电脑上自己编写的软件运行有问题,可能是编译器的版本不同引起的

  • 相关阅读:
    产品小细节中的大体验
    产品经理的四点思考:不该简单满足用户需求
    产品经理的十大顶级错误
    SQL Server数据库大型应用解决方案总结
    java中public static void main(String[] args)中String[] args代表什么意思?
    异常处理1
    java中的String
    华为2013年西安java机试题目:如何过滤掉数组中的非法字符。
    2用java代码实现冒泡排序算法(转载)
    1用java实现冒泡排序算法以及解决的几个小问题。
  • 原文地址:https://www.cnblogs.com/liuxiaowei0543/p/3682377.html
Copyright © 2020-2023  润新知