C#与Matlab混合编程_入门Author: binzhouweichao@163.com Copyright 2013, binzhouweichao@SDU, All Rights Reserved. Date: 2013-11-07 C#与Matlab混合编程基础过程。 参考: http://www./link.php?url=http://blog.csdn.net/zilin82/article/details/5466087 http://blog.sina.com.cn/s/blog_4b94ff130100d4uf.html 系统平台: Windows 7 Ultimate x64 软件版本: C#:Visual Studio 2010 Matlab:MATLAB R2011b x64(或更高版本,安装版和绿色免安装版均可,需要激活Compiler组件的License) 注: 虽然 a. VS2010不区分32位和64位系统,只区分二者的编译器; 但是 b. Matlab区分32位和64位系统; 所以 64位系统平台下只能编译64位的matlab接口,在vs2010中引用时,vs必须配置成64位平台编译。具体配置过程下面会有介绍。 32位系统无须配置vs的编译器。 1. 设置Matlab对外接口 打开Matlab,在默认的当前文件夹(Current Folder)下即可,一般为安装目录的bin目录,2013b可能是我的文档下的MATLAB目录。 新建M文件,实现两个向量(或数字)的相加,命名为sumab,位置放在默认当前文件夹下即可: function [tsum] = sumab(a, b) tsum = sum([a, b]); end 首先,配置选择C#的混合编译器VS2010,在Matlab的命令窗口(Command Window)中,键入: mbuild -setup 会弹出: Would you like mbuild to locate installed compilers [y]/n? 在弹出的选择项中,使用默认的[y](直接回车就是选择默认值),让Matlab自动搜索可用的编译器。 如果只安装了vs2010,会弹出可选编译器为: Select a compiler: [1] Microsoft Visual C++ 2010 in C:\Program Files (x86)\Microsoft Visual Studio 10.0 [0] None Compiler: 填写1,回车: Please verify your choices: Compiler: Microsoft Visual C++ 2010 Location: C:\Program Files (x86)\Microsoft Visual Studio 10.0 Are these correct [y]/n? 确认,直接回车即可。 **************************************************************************** Warning: Applications/components generated using Microsoft Visual C++ 2010 require that the Microsoft Visual Studio 2010 run-time libraries be available on the computer used for deployment. To redistribute your applications/components, be sure that the deployment machine has these run-time libraries. **************************************************************************** Trying to update options file: C:\Users\xxx\AppData\Roaming\MathWorks\MATLAB\R2011b\compopts.bat From template: D:\MATLAB\R2011B~1\bin\win64\mbuildopts\msvc100compp.bat Done . . . 其次,使用部署工具,建立.Net接口工程,在Command Window中,键入: deploytool 在弹出的部署工程对话框中,将工程名命名为sumab,Location默认,Type类型选择.NET Assembly: 点击上图所示的窗体的最大化按钮,使得新添加的窗体最大化: 要想还原,点击上图所示的按钮即可。 给新建的.NET工程添加新类,点击Build选项卡下的Add Class,添加一个新类,命名为Sumab,再点击新类下面的Add files,选择前面建立的sumab.m函数文件: 然后点击上图所示的编译按钮,编译此工程。大约1分钟左右。 编译完成后,点击Close关闭即可。 注:若出现mcc failed错误,或者cannot find ‘Compiler’,说明MATLAB Compiler工具的License未激活,解决方法是重新激活Matlab,或者重新安装已经激活Compiler工具的Matlab版本。 上述工程生成的接口dll文件位于工程所在目录(本例中为Matlab的默认current folder,即D:\MATLAB\R2011b_x64\bin)下的同名的子目录中。 里面有两个子目录,生成的dll文件位于distrib目录下。 这样,Matlab的对外接口就设置好了。 2. VS2010开始引用Matlab接口 打开VS2010,使用C#环境(默认环境如何切换可以百度)。新建C#的控制台应用程序,命名为TestMatlabCs: 为此项目添加Matlab的接口引用(Preference)。需要添加三个,分别为MLApp(mlapp,tlb),MWArray(mwarray.dll),和新建立的sumab.dll,三个引用的添加过程类似。 首先添加MLApp。 在右侧的解决方案资源管理器中,右击引用,添加引用: 在弹出的对话框中,选择浏览选项卡,找到Matlab安装目录下的bin\win64目录(本例为D:\MATLAB\R2011b_x64\bin\win64),选择mlapp.tlb: 注:32位系统为bin\win32目录。 这样,就在项目的引用中,新添了MLApp的引用: 同理,再添加另外两个引用,路径分别为: MWArray.dll:D:\MATLAB\R2011b_x64\toolbox\dotnetbuilder\bin\win64\v2.0 sumab.dll:D:\MATLAB\R2011b_x64\bin\sumab\distrib 下面,添加项目的测试代码。 目的是对两个变量a和b,调用matlab的sumab函数实现相加,输出结果。 打开项目的Program.cs文件。 首先,添加头文件引用: using MathWorks.MATLAB.NET.Arrays; 在函数体的Main函数中,定义三个变量a、b、c,类型均为MWArray(matlab的对外矩阵类型接口),a赋初值为1,b赋初值为2,c用于存放结果。 MWArray a = 1, b = 2, c; 新建matlab接口sumab的类Sumab的实例,调用其方法sumab(),计算结果: c = new sumab.Sumab().sumab(a, b); 这里偷了个懒,把建立实例并调用方法写在一块了。 将结果c转换成double类型,存储在double类型变量e中: double e = (double)(MWNumericArray)c; 这里,需要了解一下double和MWArray的转换: double <-> MWNumericArray <-> MWArray 所以,先将MWArray强制显式转换成MWNumericArray,在把MWNumericArray强制显式转换成double。 如上,转换优先级为从右向左,所以可以这样写在一块,也可以单独建立一个MWNumericArray变量,一步一步开始转换。 最后,将结果显示出来: Console.WriteLine(e); Console.ReadKey(); 这时,如果直接运行,会报错误: 未能加载文件或程序集 “MWArray” 或它的某一个依赖项。。。 原因是,MWArray为64位Matlab对外接口,而VS当前使用的编译平台为32位,所以需要配置VS编译器为64位。 参考:http://www./thread-160339-1-1.html 点击VS工具栏Debug右侧的下三角,打开配置管理器: 在弹出的配置管理器对话框中,点击平台的右侧下拉三角,选择新建: 在弹出的新建项目平台中,选择新建平台为x64,从此处复制设置为<空>: 这样,就可以编译运行项目了。 Program.cs代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using MathWorks.MATLAB.NET.Arrays; namespace TestMatlabCs { class Program { static void Main(string[] args) { MWArray a = 1, b = 2, c; c = new sumab.Sumab().sumab(a, b); double e = (double)(MWNumericArray)c; Console.WriteLine(e); Console.ReadKey(); } } } |
|