Matlab2013b和Visual Studio 2013混合编程总结

本文详细介绍了如何在Matlab2013b和Visual Studio 2013之间进行混合编程,包括软件版本选择、系统环境变量设置、Matlab编译器的配置、DLL文件生成以及C#调用DLL的步骤。通过实例展示了如何在C#中调用Matlab函数,同时提供了异常情况的解决方案和相关参考资料。

 Matlab2013b和VisualStudio 2013混合编程总结

 

一、       关于软件版本和安装的说明

一般来说,Matlab版本需高于或者等于VisualStudio的版本。综合版本功能和兼容问题,我们选用了Matlab 2013b和Visual Studio 2013。 

Matlab2013b能够识别VisualStudio2012版本,前提是Visual Studio2012装在C盘默认目录。如果安装的是2013版本的话,Matlab无法识别,但是可以手动选择路径使得Matlab找到VS的编译器。详细的图文说明在第三部分说明。

二、       系统环境变量的设置

Computer -> Properties -> Advanced system settings ->Environment Variables -> User Variables -> path,添加Matlab2013b的安装路径:

…\MATLAB\extern\lib\win64\microsoft;

…\MATLAB\bin\win64

 

Computer -> Properties -> Advanced system settings ->Environment Variables -> System Varables -> path,添加路径:

…\MATLAB\runtime\win64;

…\MATLAB\bin;

…\MATLAB\extern\lib\win64\microsoft;

…\MATLAB\bin\win64;

 

三、       Matlab的设置以及DLL文件的生成

<一>Matlab的设置

在Matlab中设置编译器的时候,经过测试,存在两种情况。分别说明如下:

情况一:

>> mex –setup

>> y

如上所示,Matlab没有找到编译器。此时的问题可能是:1.没有安装SDK,在上面截图中的蓝色的网址中下载SDK并安装;2.没有安装Matlab2013b能识别的VS或者VS没有安装在默认文件夹。

如果是问题1则需要下载安装SDK

如果是问题2的话,则重新输入>>mex –setup然后选择n

如上图所示,Matlab弹出了它所支持的编译器,此时选择[18]或者其他MVC,然后弹出提示后,选择n,自己手动添加路径,添加VS2013的安装路径。

弹出提示后选择y。显示一下界面则是成功了。

 

接下来输入mbuild -setup,设置方法同mex –setup。

至此,Matlab 编译器设置完毕。

 

情况二:

只找到了matlab的编译器,没有找到vs的:

那么有两个解决方案,在C盘在安装一遍vs,或者是选择n然后跟情况一的问题2一样操作。最好最顺利的情况是按y有出现vs编译器。

<二>DLL文件的生成

1.首先编写.m文件并保存。

例如myadd2.m:

2.建立DeploymentProject

方法一:在matlab命令窗口输入 >> deploytool 弹出如下界面,选择ApplicationCompiler。

方法二:在Matlab菜单栏选择APPS,选择Application Compiler

 

选择Application Compiler后出现以下界面:

如图所示进行操作。这里需要注意的是,matPrj是matlab的Project名,同时也是生成的DLL文件名和C#中的命名空间名称,而maMathClass则是命名空间中的类名,MatrixOpera和myadd2则是类中的方法名称。

最终在输出文件夹里找到几个关键文件:

主要是DLL文件。在Matlab的安装目录下:

…\MATLAB\toolbox\dotnetbuilder\bin\win64\v2.0中找到MWArray.dll,然后将MWArray.dll和prj.dll拷到C#的工程中的Debug文件夹中。

四、       Visual Studio的设置以及C#调用DLL文件

Matlab和C#混合编程的时候,VS不需要特殊的设置,Matlab和C++混合编程的时候VS设置比较麻烦,这个在后面再做说明。以下讲C#的设置。

在VS2013中建立C#窗体应用程序

建立完之后需要往工程里面添加引用。

如上,在引用那里右键添加引用,然后点击浏览找到MWArray.dll和prj.dll并添加,结果如图所示,点击确定退出。

 

在需要使用prj中的函数的文件里面添加如下命名空间说明:

using MathWorks.MATLAB.NET.Arrays;

using MathWorks.MATLAB.NET.Utility;

using matPrj;

 

为了简单的测试,可如下操作:

在窗体中添加两个textbox和一个button。

双击button,在private voidbutton1_Click(object sender, EventArgs e)中添加程序:

 

           matPrj.prj.maMathClass output = new matPrj.prj.maMathClass();//实例化maMathClass类

 

            MWArray a = 2;//建立MWArray类以便Matlab识别

            MWArray b = 3;

 

            MWArray[] x =output.myadd2(2, a, b);

 

            MWNumericArray y =(MWNumericArray)x[0];//提取输出y,z

            MWNumericArray z =(MWNumericArray)x[1];

 

            double[,] y1 =(double[,])y.ToArray(MWArrayComponent.Real);

            double[,] z1 = (double[,])z.ToArray(MWArrayComponent.Real);

//将y,z转化为C# 数组

            double y2 = y1[0,0];

            double z2 = z1[0,0];

            textBox1.Text =y2.ToString();

            textBox2.Text =z2.ToString();

这段程序应该这样理解,输入a和b可以是两维数组,相应的输出y和z也是两维数组,y是第一个两维数组,z是第二个。

其中y1和在z1是转换成C#的数组,y2和z2是提取数组中的第一个元素

编译并运行程序,点击button,结果如下:

测试成功!

 

异常情况:

可能会出现类型初始值设定异常

解决方案如下:

1. 重新安装MCR,选择安装路径为C:\MCR (不含空格,中文)

2. 确保环境变量正确 path后添加:C:\MCR\v713\runtime\win32

3. 运行 -> regsvr32 mwcomutil.dll

4. 重新build .dll文件,package中选择add MCRsetting中设置assembly typesharedencryption keyfile设为空,再把新生成的dll文件拷贝到那台电脑,替换,重新引用

5. 重启 or 重启VS

详情见http://blog.csdn.net/kindlucy/article/details/7110329

 

五、       Visual Studio的设置以及C++调用DLL文件

六、       变量的转换说明

   函数调用前需要转换变量:

(1)将c#的参数输入到matlab函数时,要将参数转化为matlab的参数形式,通常是MWArray类型。 

(2)matlab返回的参数,也要转化为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#等语言的转换中间类型。 

已经添加了的引用 

 

常用的转换函数:       

① 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); 

 

(3)必须注意到多参数输入和多参数返回的问题。刚开始碰到这个这个问题比较头疼,后来经过不懈的努力,终于从网上找到答案。 

声明这部分是我参考别人的想法自己写的额,网上百度知道也有我(lwq123_321)回答的。 

//输入这里想传入的2个输入参数,为了支持矩阵好通用,所以得弄成Array             double[] a = { 1, 2, 3, 4, 5, 6 };//输入参数1             double[] b = { 2, 4, 6, 8, 10, 12 };//输入参数2             double[,] c = new double[3, 2];//输出参数1             double[,] d = new double[3, 2];//输出参数2 //这些参数都是矩阵 

            MWNumericArray ma = new MWNumericArray(3, 2, a);//转换成matlab需求的格式 

            MWNumericArray mb = new MWNumericArray(3, 2, b);  

//输出参数是一个MWArray数组 

            MWArray[] agrsOut = new MWArray[2];//两个输出参数,一定要写数量 

            //输出几个输出参数可以是不同类型的,比如第一个元素是矩阵,第二个是数值 

 //同理,输入参数也是一个MWArray数组 

            MWArray[] agrsIn = new MWArray[] { ma,mb}; //调用函数,输出参数需要加 ref 关键字 

            myFun.MatrixOpera(2, ref agrsOut, agrsIn);                         //2表示输入参数的个数,输出结构都在argsOut中,类似于c的指针参数输入 //转换得到实际的输出参数 

            MWNumericArray x1 = agrsOut[0] as MWNumericArray;                        MWNumericArray x2 = agrsOut[1] as MWNumericArray; 

                       c = (double[,])x1.ToArray();                       d = (double[,])x2.ToArray(); 

//一定要注意最后c和d的转化,不同类型的转换差异很大厄 //ToArray()对应n*m的数组 

//ToScalarDouble()对应单个数值 //ToVetor()对应1维数组

七、       参考资料

1.     C#调用matlab函数(混合编程)

http://wenku.baidu.com/view/77cf1e60f5335a8102d220e3.html

2.     浅谈C#与matlab的混合编程

http://wenku.baidu.com/link?url=Q3URh3KbXQi4JZUnFhvTUoMZDSAH97tdk3lwVr0fMQRc7Wx4k0HNYG4VHeW019GleyiivdeTTeYdVFtyam0NNkJZ5M6GR5yo9ltxvGSXgI3&qq-pf-to=pcqq.c2c

 

3.     小记Matlab与C#混合编程

http://blog.csdn.net/kindlucy/article/details/7110329

 

4.     MatLab和C++的混合编程-VS2010环境下的配置

http://wenku.baidu.com/link?url=Hf-i7UsvqZRhE_7NhDh4HxtTm8BuuoBt7K34-On17gueAHeCzEKZNHobsMlT-pSd0yz7yGPwU_1DVPcTIPy5Z_7PGy2zRUKSXT2V1SQqxIS

 

5.     vs2010和Matlab R2012b 混合编程

http://blog.csdn.net/stardust94605/article/details/8972064

 

6.     VS2013调用matlab2013b引擎混合编程问题(无法解析外部符号)

http://www.ilovematlab.cn/thread-292626-1-1.html

 

7.     visualc++中预定义的宏

http://www.cnblogs.com/tocy/p/4090459.html

 

8.     matlab2013不支持vs201

http://blog.csdn.net/gotomic/article/details/29594247

 

9.     MEX-filesGuide

http://blog.csdn.net/gotomic/article/details/29592553

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值