【从业余项目中学习2】C# 实现调用Matlab函数(Visual Studio:2008, Matlab:R2009a)

  最近正在给客户做的个人项目,要求实现C#与Matlab之间的调用,即C# winform界面收集用户输入的参数,将参数传递给Matlab的算法计算,Matlab函数返回的结果显示在winform界面上。

  网上此类的文章较多,但自己在实现过程中还是有些差别,所以在项目进行之前,自己写了一个测试的例子来实现C#对Matlab函数的调用

一.  测试用例简介

  功能:Matlab函数计算两个数值a与b的和,a与b的值由C#提供,和值c经Matlab计算得出后,返回给C#

  环境:Microsoft Visual Studio 2008

     Matlab R2009a(Version 7.8.0.347)

  备注:由官网可知,Matlab对类似其他程序调用都提供了很好的支持,这里没有选择VS版本大于Matlab版本,是因为担心Matlab版本只支持自己之前的VS版本。

二.  实现步骤

  1. 实现Matlab函数

    A. 打开Matlab R2009a,新建testAdd.m文件

    B. testAdd.m中实现加法函数

1 function y = testAdd(a, b)
2 y = a + b;

  2. 编译testAdd.m,得到DLL文件,以便由C#引用

    A. 在Matlab命令行中输入"deploytool",即可弹出"Deployment Tool"工具窗口

      在网上看很多资料,执行"deploytool"命令之前都需要安装Matlab编译器(命令:"mbuild -setup"),但我不这样做,也可编译。怀疑是否与我将VS,Matlab都装在一台机器有关。另外即便我执行这安装命令,也找不到正确的编译器。总之,我并没有按照网上教程,直接"deploytool"即可。这也提醒自己:实践过后,才知是否正确,不要盲目听从别人方法。

    B. 编译DLL,需要在"Deployment Tool"工具窗口中新建Deployment project

      这里我建了名为"test"的工程,选择project类型时,应选择.NET Component,因为这里我需要其作为C#的引用。同时注意这里的工程名,即是你编译出DLL的名称,同时C#程序调用时,"Test"即为封装Matlab函数的类名。他将你的工程名,首字母大写用为高级语言中的类名。

    C. 配置"test" project

      首先将testAdd.m添加到test工程下Test文件夹中(右击Test,选择Add File)(注意:这里不要使用中文路径,详见下方六.测试过程中Bug记录)。

      其次选择Setting,在设置中,配置.NET Microsoft Framework,由"Default"改为"2.0",不能用默认。网上说法是否则编译出的DLL会有问题。

      注意:这里网上许多资料讲,要将Assembly Type设置为Shared,但我发现如果这样,必须要提供Encryption Key的文件路径,这个就没法提供了。所以我并没有这样做,事实上没有影响。疑惑的地方。

    D. 点击"Build"编译文件(如下图所示)

     即可在test\src路径下得到编译后的DLL文件

  3. 实现C#程序,调用Matlab编译出的DLL

    A. C#项目中,导入Matlab DLL引用

      导入的文件:test.dll, testNative.dll, MWArray.dll(%matlabpath%\toolbox\dotnetbuilder\bin\win32\v2.0,MWArray是用于C#与Matlab之间的数据交换类,传值,取结果都用到它)

    B. 实现C#调用代码

 1 using System.Data;
 2 using System.Drawing;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows.Forms;
 6 using MathWorks.MATLAB.NET.Utility;
 7 using MathWorks.MATLAB.NET.Arrays;
 8 using test;
 9 
10 namespace testMatlab
11 {
12     public partial class Form1 : Form
13     {
14         public Form1()
15         {
16             InitializeComponent();
17 
18             label6.Text = "";
19         }
20         
21         private void button1_Click(object sender, EventArgs e)
22         {
23             //Get input number from UI
24             int iTextBox1 = int.Parse(textBox1.Text.ToString());
25             int iTextBox2 = int.Parse(textBox2.Text.ToString());
26                         
27             MWArray result = null;
28             MWNumericArray a = new MWNumericArray(iTextBox1);
29             MWNumericArray b = new MWNumericArray(iTextBox2);
30 
31             
32             //call function testAdd, provided by Matlab
33             Test t = new Test();
34             result = t.testAdd((MWArray)a, (MWArray)b);
35 
36 
37             int y = ((MWNumericArray)result).ToScalarInteger();
38             
39             //show result in UI
40 
41             textBox3.Text = y + "";
42             label6.Text = "Get the result by Matlab DLL, Answer: " + y;
43         }
44     }
45 }

三.  执行C# winform程序,验证计算结果,确定是否执行了Matlab函数调用

    1. 输入初值

    2. 得到结果

四.  小结

  由此,可实现C#对Matlab算法的调用。当然这里只是自己开发需要时,设计的一个小例子。由于Matlab计算,输入与结果需要大量的矩阵,那C#与其之间的数据交换也是通过MWArray进行,只要遵循接口规范,都可以实现。这里不再研究,网上资料也很多。

五.  完整的测试例子附件

  Matlab函数:http://files.cnblogs.com/KevinSong/testMatlab.zip

  C#程序:http://files.cnblogs.com/KevinSong/Test.zip

六.  测试过程中Bug记录

  1. 调用DLL时,程序报错"MathWorks.MATLAB.NET.Utility.MWMCR.mclCreateComponentData,错误描述是:传递给系统调用的数据区域太小"

    解决方法:不能使用中文路径的.m文件,可能会有诡异的问题产生

    参考链接:http://hi.baidu.com/ssemo/item/4caab7f3a0765ec20dd1c888

虽然网上参考资料很多,但经过自己实践,还是发现一些不同的小地方。项目进行前,通过一个小的测试例子来证明技术路线可行。希望对需要的同学有帮助。抛砖引玉:-)

Best Regards

Kevin Song

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python小屋

Python模拟分析演员之间亲密程度

假设当前文件夹中有Excel文件“电影导演演员.xlsx”,其中数据格式如下图所示:

702
来自专栏林德熙的博客

win10 uwp win2d 使用 Path 绘制界面

在 win2d ,可以使用 DrawGeometry 的方式画出几何。而路径 Path 就是一种 Geometry 。传入的 CanvasGeometry 参数...

331
来自专栏逸鹏说道

Toxy新手教程

Toxy新手教程 官方网站:http://toxy.codeplex.com Toxy是干嘛用的?它是.NET平台上的文件抽取框架,主要解决各种格式的内容抽取问...

2656
来自专栏Y大宽

RNA-seq(5):序列比对:Hisat2

1 HISAT2官网下载 人类和小鼠的索引有现成的,HISAT2官网可以直接下载进行序列比对。如下图所示:选择hg19和mm10的index,文章中RNA-S...

882
来自专栏计算机视觉life

OpenCV学习入门(一):人脸检测

关于OpenCV网上的学习资料非常多,尤其是很多比较专业的技术博客,对学习计算机视觉的筒子们真的是个非常好的帮助~踩在这些巨人们的肩膀上,我打算一步一个脚印从零...

2899
来自专栏点滴积累

geotrellis使用(二十二)实时获取点状目标对应的栅格数据值

目录 前言 实现方法 总结 一、前言        其实这个功能之前已经实现,今天将其采用1.0版的方式进行了重构与完善,现将该内容进行总结。        其...

3535
来自专栏韩东吉的Unity杂货铺

零基础入门 30:获取移动端手机的电量/时间/网络

大家在玩手游的时候经常会看到游戏里有一些提醒状态,图示如下,右上角有当前手机端的时间,wifi网络状态展示,以及电量的展示效果

303
来自专栏生信技能树

(14)不同基因坐标转换-生信菜鸟团博客2周年精选文章集

主流有3个,我只介绍了两个: 用crossmap代替liftover做基因组坐标转换 liftover基因组版本直接的coordinate转换 其实国际三大主流...

42113
来自专栏王磊的博客

Xamarin开发笔记—百度在线语音合成

续《是时候开始用C#快速开发移动应用了》刷屏之后,把C#开发移动应用的技术 => Xamarin,在这里和大家做一个分享! 语音合成:也被称为文本转换技术(TT...

2485
来自专栏快乐八哥

数据可视化-EChart2.0.0使用中遇到的2个问题

之前项目中都是使用FusionChart和HighChart,基本都是没有购买商业许可。然后现在开发的系统需要交付给客户使用。所以现在图表控件不能直接使用Fus...

722

扫码关注云+社区