c#调用matlab中如何调用函数函数的问题

有的时候用C#写图像处理方法,比较费事,不如Matlab简单,但是Matlab又做不出WPF那样的好看界面,怎么办呢。今天正好我要实现这个功能,就顺便写个小例子,给需要的人做个借鉴。想要用WPF调用Matlab代码,就用到了Matlab生成.DLL文件的功能。注:我的VS版本是2013,Matlab版本是2012a,两个软件不算新也不算老,应该是现在普遍用的版本首先,生成Matlab的.DLL文件在matlab的左下角选择start-matlab-NE-deploytool,或者直接在command界面输入deploytool。在弹出的对话框里,输入你需要输入的内容,可以默认,也可以手动填入,Type选项一定要选择.NET Assembly选项。在Matlab窗口右侧会出现一个对话框,点击Add Class增加一个Class,名字自己填写,然后点击Add Files,选择需要的生成DLL的Matlab函数文件。然后点击Build按钮,等待进度条走完当进度条走完以后,在刚才的目录下会生成一个以name命名的文件夹,此文件夹下会有两个文件夹,分别是distrib和src。在WPF程序下进行引用,浏览,找到MWArray.dll,我的路径是&D:/Program Files/MATLAB/R2012a/toolbox/dotnetbuilder/bin/win32/v2.0&,这个也就是前面会根据不同人安装的Matlab路径不一样而不一样,后面基本是一样的,同时引用distrib文件夹下的JLFG.dll文件。在WPF的代码中进行引用using MathWorks.MATLAB.NET.Ausing MathWorks.MATLAB.NET.Uusing JLFG;写实现部分代码string proPath = selPath();JLFG.Iorig iorig = new Iorig();iorig.I_orig(proPath);ImgPro.Source = BitImg("C://I_orig.jpg");中间的两行代码为调用实现部分,第一行代码是获取图片的路径,最后一行是展示图像用的。因为Matlab输出是直接用Figure输出,因此需要imwrite进行保存,因此才有了最后一句的调用图像路径。最终的实现效果但是,有一个问题出现了,就是我实现的过程用的是Win7 32位的的系统,没有问题,用Win8.1 64位系统就不好使,虽然更换了MWArray.dll的路径为64位的路径,依然不好使,出现如下错误,有知道如何解决这个问题的大神,请告知方法,在此谢谢了。&
无相关信息相关文章推荐:
添加 mathworks 引用
使用vs2005和matlab混合编程
调用不带参数的 .m函数文件,没有出现问题。
test.testclass TEST = new test.testclass();
TEST.huatu();
需要调用带参数的 .m函数文件,就出现问题了,
Average.Averageclass A = new Averageclass();
A.average(20);
错误 : 找不到类型或命名空间名称“MathWorks”(是否缺少 using 指令或程序集引用?)
错误 “MathWorks.MATLAB.NET.Arrays.MWArray”在未被引用的程序集中定义。必须添加对程序集“MWArray, ...
回复 (2) 浏览 (3519)
其他文章推荐
ITPUB官方微博:
请教高手,工单报工调用BAPI:BAPI_PRODORDCONF_CREATE_TT,如何实现反冲料件错误直接报错,不要后处理?谢谢!...
回复 (2) 浏览 (60)
小弟在应付账龄报表开发过程中遇到了一些问题,算账龄的时候基准日期取哪个呢?是用户给截止日期的参数和基准日期的类别,过了截止日期之后的余额算账龄,还是截止日期之前按支付时间和基准日期相减算账龄?...
回复 (2) 浏览 (3976)
拍卖规则:您出的价格,必须是您itpub帐户财富以内的价格,出价成功以后,系统立即扣除相应pub币,并且显示您的竞价记录。竞拍期间您出价的pub币将被冻结,在拍卖结束后系统将自动把竞拍出局会员的pub币统一归还。胜出者出价时间以拍卖帖规定的结束时间为准(例如结束时 ......
回复 (38) 浏览 (725)
过账时,提示“没有控制范围分配给公司代码”,如下图但是我已经在全局参数设置维护过也给信贷控制范围分配过公司代码为什么过账时还是提示“没有给控制范围分配公司代码”?这里的控制范围是指信贷控制分为还是成本控制范围?...
回复 (11) 浏览 (176)
如何动态判断一个表的多个字段值是否为空,没有比较好的判断方法?一个表有N多个字段,应如何判断有些字段的值是空?通用的函数?--...
回复 (6) 浏览 (186)
一:使用route命令添加使用route命令添加的路由,机器重启或者网卡重启后路由就失效了,方法://添加到主机的路由#routeadd–host192.168.1.11deveth0#routeadd–host192.168.1.12gw192.168.1.1//添加到网络的路由#routeadd–net192.168.1.11&netmask255.255.255 ......
回复 (6) 浏览 (100)
usingSusingSystem.Collections.ponentMusingSystem.DusingSystem.DusingSystem.TusingSystem.Windows.FusingSystem.Data.OracleC//引入oracle的连接对象命名空间namespacelearncomboxanddatagridview{& ......
回复 (3) 浏览 (154)
SQL&SELECTSALSALARYFROMEMPWHERESALARY&2500;Warning:connectionwaslostandre-established&SELECTSALSALARYFROMEMPWHERESALARY&2500&ORA-00904:&SALARY&:标识符无效&在ORACLE中,在WHERE子句中引用列别名会出错,这是为什么呢 ......
回复 (3) 浏览 (1852)
数据文件达到最大值以后,oracle有没有自动添加一个新的数据文件的功能,还是必须要手工添加呢?...
回复 (6) 浏览 (550)
此文档描述了如何在3494带库中添加新的3592磁带,并将新加入的磁带分配到TSM服务器所管理的存储池中。1.&&&&&磁带准备被添加入库的3592磁带,应具有物理标签(条形识别码),并可以被自动磁带库识别。磁带介质准备好后,打开3494自动 ......
回复 (3) 浏览 (1346)
文章推荐:
盛拓传媒:
友情链接:
特别鸣谢:
北京皓辰网域网络信息技术有限公司. 版权所有
北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证:编号(京)字第1149号
ITPUB推荐文章解答你所有技术难题c#与matlab混合编程,m文件里的函数能不能嵌套调用,?几个m文件能放在一个dll里面吗?
c#与matlab混合编程,m文件里的函数能不能嵌套调用,?几个m文件能放在一个dll里面吗?
能不能嵌套没试过,应该可以的,m文件放一个dll是可以的,每个m文件在C#中就是一个类,dll的名字是命名空间。
相关知识等待您来回答
编程领域专家
& &SOGOU - 京ICP证050897号Matlab COM Server的VC++程序调用_教育学习-牛bb文章网您的位置:&>&&>&Matlab COM Server的VC++程序调用Matlab COM Server的VC++程序调用(原作者:沈智娟 杨贺来 王淑芬 张为民)摘要:工程中往往需要VC++编写的程序进行大量的数学计算,如能在程序中使用Matlab的例程这些问题则能迅速解决。在Windows平台上Matlab 提供了两个实现这一目标的接口――Matlab Engine和Automation Server,两者在本质上都基于COM技术。引擎库通过其输出函数对用户屏蔽了底层的COM细节,这大大方便了使用。而使用自动化服务器就要使用COM的自动化接口IDispatch,不过MFC库的COleDispatchDriver类已使这一过程大大简化了。两种方式的差别主要体现在参数传递和返回值处理上,如文中代码所示。无论哪种方法,都可以将具有强大工程计算能力的Matlab接入VC++程序,从而快捷方面地解决许多数值计算和图形输出问题。关键词:Matlab外部接口;混合编程;VC++;COM;自动化中图分类号:TP311文献标识码:A文章编号:08)36-2792-04Program with Matlab COM Server in VC++SHEN Zhi-juan1, YANG Hei-lai1, WANG Shu-fen2, ZHANG Wei-min3 (1.Mechanical Engineering and Automation Department, Beijing University of Aeronautics and Astronautics, Beijing 100083, C 2.Computing Center, Hebei University of Science and Technology, Tangshan 063009, C 3.Beingjing Aeronautic Manufacturing Reseach Center, Beijing 100024, China) Abstract: Programs written in VC++ sometimes need to do calculation intensive jobs, which can be solved swiftly if some Matlab function can be called inside the program. Matlab provides two methods to achieve this: Engine Library and Automation Server, both of which are based on COM. Engine Library made the custom COM interface IEngine transparent to the Client through its export functions while MFC class COleDispatchDriver encapsulates the detail of interacton with the COM Automation interface IDispatch. The given code in this article shows differences of the two method come mainly from the parameter passing and result retrieving process. With either method, Matlab can be linked into the program and thus make the calculation and figure output tasks be achieved faster and easier. Key words: matla VC++; COM; automation1 引言Matlab提供的编程语言――M语言――是以方便数值计算编程为目的设计的,所以其基本数据结构就是矩阵,且其变量的具体类型和大小可在执行时动态确定,这对编写数值计算程序提供了很大的便利。另外,由于M语言可直接调用Matlab提供的各种数学和面向工程应用的工具箱函数,所以使用M语言还可以迅速地解决许多计算量很大的工程问题。但另一方面,由于M语言是一种解释型编程语言,所以它的执行效率较低,另外其在开发应用程序界面和对外围设备的控制能力上也较差。另一方面,其他的编程环境,如VC++,则在这些方面提供了很好的支持,但如用其进行数值计算或解决工程问题又会非常不便。故如果对软件界面、外围设备控制、数值计算三方面都有较高的要求,一个理想的方案是在像VC++这样的编程环境中实现界面及外设控制功能,并在其中调用Matlab环境中的模块,如其工具箱函数,作为计算工具。在VC++程序中调用Matlab有两种方法:一是通过Matlab提供的引擎库(Engine Library),它的本质是一个拥有定制接口IEngine的COM服务器;二是通过Matlab提供的COM Automation Server。本文将首先介绍COM和Automation技术的原理和应用方法,之后介绍这两个接口,并随后给出在C++中使用两者的具体方法。 2COM与Automation2.1 COM概述组件对象模型(Component Object Model,COM) 由Microsoft于1993年创建,它规定了dll、exe等应用模块之间进行交互的步骤和方法。在COM之前,一个应用程序(Client)如果要使用dll文件(Server)输出的功能就要使用Win32 API函数LoadLibrary,GetProcAddress,要使用exe文件(Server)输出的功能除了需使用相关的Win32 API函数外,还要使用基于Windows消息机制的DDE协议。COM则是Microsoft新推出的这些方法的换代品,它解决了不少在使用老方法时产生的问题,如他们本质上是面向过程的技术,使用起来比较零散复杂,且对系统来说,他们是无法管理的。COM则提供了一个面向对象的Server功能管理及Client/Server的通讯方法。但这需要应用编程者的配合,即COM不仅是Windows操作系统新增的一系列数据结构和函数,而且是一系列应用与系统交互方式的定义。在COM中,Server模块(dll或exe)要向系统注册其输出的COM类,即在注册表中保存COM类的GUID(Global Unique Identifier),Server模块完整的路径及文件名等相关信息。一个Server模块可拥有多个COM类。于是,Client只要向系统提供其所需COM类的GUID系统就能找到包含这个类的模块并加载它。在注册COM类的同时,Server还要注册每个COM类所包含接口(interface)的GUID。从功能上说,一个接口就是Server输出的一个功能单元,它由一组功能上密切相关的函数指针构成;而用C++语言表达,COM接口就是一个仅包含虚函数的结构体,它本质上是一个包含一个函数指针数组的内存结构,这一内存结构是由Microsoft定义的标准。Client则是通过GUID向系统提交自己的请求,通过获得由Server提供的接口指针来调用Server的输出函数[1]。(原作者:沈智娟 杨贺来 王淑芬 张为民)事实上,接口是COM技术的核心要素,其最基础的接口是Microsoft定义的标准接口IUnknown,它包含QueryInterface、AddRef和Release三个函数,这些函数是Client与Server通信的基础。而所有其他的接口均需继承自IUnknown。这也是C++多态技术的一个应用。除了IUnknown,Microsoft还定义了许多其它接口,这些接口事实上是许多编程技术的底层基础,如IDispatch接口就是Automation技术的根本核心。同时需要说明的是,对其制定的大部分接口而言,Microsoft只是定义了接口的数据结构,接口函数功能的实现要由Server开发者完成。可见,COM是一个Client、Server和操作系统协力合作。从操作系统的角度看COM是一个记录COM类的方式和一组用于Client和Server通信的API函数。对Client来说COM是利用API向系统发出请求并利用接口指针使用COM类的功能。对Server来说则是利用API注册自己,实现所有接口函数,这包括由Microsoft定义的接口函数,如Server必须实现IUnknown接口的QueryInterface函数,其作用是为Client提供其所要求的所有接口指针。2.2 Automation概述由于接口本质上是一个包含一个函数指针数组的内存结构,这一内存结构是由Microsoft定义的标准,而所有支持COM的编译系统和语言对接口的处理都符合这一标准,所以通过COM,就可实现不同编译器、不同语言编写的应用顺利通信。但是仍有一个问题,就是想Visual Basic这样的解释性语言无法学习C++定义的接口。举例来说,如果一个C或C++程序要使用一个组件定义的接口IMath,它就需要声明接口的结构,如:struct IMath : IUnknown{virtual void Add(int a, int b) = 0;virtual void Multiply(int a, int b) = 0;virtual void Square(int a) = 0;};这样,在获得了接口指针,不妨叫pIMath,之后,就可以用“pIMath-&Add(a, b);”这样的语句来使用Server的功能。但Visual Basic却不支持这样的语法,即它的解释程序无法以函数指针的形式学习新的接口定义。考虑到接口将会不断增长的事实,让Visual Basic把对所有接口的支持固化在解释程序中又是不可能的。所以,为了解决这类问题,Microsoft定义了IDispatch接口,其思想是,像VB这类语言的解释程序只需要支持IDispatch接口,就可以在执行时通过Server获得其需要函数的相关信息,从而完成调用。整个接口的机制是Server要为输出的函数分配一个数字ID和一个相对应的标识字符串。Client只知道标识字符串,为了调用相应的函数,Client在获取IDispatch接口指针后,先调用其函数GetIDsOfNames()得到和标识字符串相对应的数字ID,再调用IDispatch的函数Invoke(),该函数专门负责根据输入的数字ID找到Client要求的函数,并调用它。Invoke()在调用函数时需要传递参数,而参数格式是无法由解释程序预知的,所以Invoke()使用了一种特殊的数据类型VARIANT来解决这一问题。VARIANT是一个结构体,它可以表示任何类型的数据。VARIANT主要由两部分组成,一是标识数据类型的vt,二是存储实际数据的union结构。函数的输入参数就被存储在一个VARIANT数组里被传递给Invoke。当然,之后解析各个变量并传递给输出函数的任务就交由Invoke()完成了。函数的返回值同样是以VARIANT形式回传的。这样,就解决了高级语言使用COM组件的问题。所以,自动化(Automation)是建立在COM基础上的。一个自动化服务器实际上就是一个实现了IDisPatch接口的COM组件。而一个自动化控制器则是一个通过IDisPatch接口同自动化服务器进行通信的COM客户。3 Matlab 提供的COM Server接口由于出现了Automation技术,访问COM组件就有了两种方式:①通过普通的自定义的COM接口访问组件;②通过调度接口IDisPatch访问组件;如果一个组件同时实现了这两种接口,则称为双重接口,那么客户就可自由的选择其中的一种方式访问组件的功能。Matlab就提供了这两种接口。3.1 IEngine 接口IEngine是Matlab提供的定制接口,但通常在程序中不会直接使用它,而是使用Matlab提供的引擎库(Engine Library)函数。事实上,COM Server及其接口IEngine可看作是引擎库在Windows平台上的实现手段。当然,也可以把引擎库看作Matlab为方便IEngine的使用而提供的函数库。在使用引擎库时,完全不需要COM的知识,只需要把它看成一个非标准的C语言静态函数库即可。引擎库共输出了9个函数,通过它们可以方便的开始和结束与Matlab Server的对话,设置命令窗口(缺省状态是显示命令窗口),与Matlab的工作空间交换变量,执行任何可在Matlab命令行执行的命令。使用引擎库和直接在Matlab命令行输入的方法是极为类似的。3.2 IDispatch 接口IDispatch是Matlab为Visual Basic,C#等语言提供的接口,但在C++程序中也可以使用,只不过,这需要进行较多和COM相关的编程。如果使用VC++提供的MFC类COleDispatchDriver来使用Matlab 自动化服务器,则可以大大简化这一过程。这些内容后面会详细讨论。通过IDispatch接口获得的函数功能和引擎库类似,但功能更丰富更灵活些。例如,如果要调用统计工具箱的方差计算函数求某一双精度数组的方差,使用引擎库函数的流程必须是先通过engPutVariable()将数组存入Matlab,比如起名叫“a”;再用engEvalString()命令执行一条语句“b = std ( a )”,这在执行命令的同时又在Matlab里建立了变量“b”;最后通过engGetVariable()将变量&b&取回。Matlab的自动化服务器则除了拥有支持上面流程的函数外,还提供了另一种可能性,即只需调用函数Feval()就可以了,因为Feval()可同时接受函数名,参数作为输入,并将Matlab的计算结果输出。4 Matlab COM 接口的VC++调用在VC++中使用Server的关键问题有两类,一类是如何启动和释放Server,另一类是如何与Matlab进行数据交互。下面将分别针对这两方面,以一个具体的问题――方差的计算,待计算的数据保存在变量double Array[20]中――为例,说明调用Matlab 两种COM接口的具体操作。下面的代码均经过实际测试使用,其环境为WindowXP,Visual C++ 6.0和Matlab 7.4.0。4.1 Server的启动和释放(原作者:沈智娟 杨贺来 王淑芬 张为民)4.1.1 引擎库使用引擎库在创建工程时不需要特别设置,但之后第一要在源文件中包含engine.h,它其中声明了引擎库函数的原型。engine.h中还包含头文件matrix.h,其最主要的内容是定义了数据类型mxArray及对它进行操作的函数原型。mxArray类型是许多引擎库函数的参数类型,它是C++程序和Matlab进行数据交互的工具。而matrix.h中又包含tmwtypes.h,这一头文件中也定义了一些数据类型。三个头文件的路径均为Matlab安装目录下的extern\include。将engine.h包含入源文件有三种方法,其一是在源文件中包含完整的路径和文件名,如“#include &D:\matlab\extern\include\engine.h”;其二是仅包含文件名,但把上述三个头文件全部拷贝到工程目录中;其三也是只包含文件名,但要在VC++ 6.0的Tool菜单的Option命令对话框的Directory选项卡中,把头文件所在路径添加到include搜索路径中。这之后,还要为工程加入两个库文件――libeng.lib和libmx.lib,其中libeng.lib实现了引擎库函数,而libmx.lib则实现了操作mxArray需要的各个函数。它们路径均为Matlab安装目录下的extern\lib\win32\microsoft。具体操作为右键单击VC++ 6.0左侧Workspace里FileView的工程文件,在弹出菜单中选择“Add File to Project”,之后在弹出的对话框中转到上述目录后将文件过滤设为“Library Files”就可以选择所要的库文件了。为方便代码的移植,则可以先将上述文件复制到工程所在目录再进行添加。在做好这些准备工作后,就可以正式使用引擎库了。引擎库启动可使用如下代码:Engine *if (!(ep = engOpen(&\0&))) {fprintf(stderr, &\nCan't start MATLAB engine\n&);}结束与Matlab的对话可使用:engClose(ep);4.1.2 自动化服务器在C++程序中直接用Win32 API操作自动化服务器是比较繁琐的,所以笔者对自动化服务器的操作是通过MFC的COleDispatchDriver类完成的。这就要求在创建工程时要加入对MFC类的支持。之后,启动Class Wizard,单击其新建类按钮中的“从类库(type library)”命令从而打开“从类库导入”为标题的对话框。在对话框中转入Matlab安装目录下的bin\win32文件夹,选择其中的mlapp.tlb文件就可以生成继承自COleDispatchDriver类的DIMApp类。完成上述工作,就可用下面代码启动Matlab自动化服务器:DIMLApp MatlabACOleException *e = new COleEtry{if (!MatlabAuto. CreateDispatch(&matlab.application&, e)) throw(e);}// Exception handling code.其中,函数CreateDispatch()是从基类COleDispatchDriver继承的。结束自动化服务器可用如下代码:MatlabAuto.ReleaseDispatch();函数ReleaseDispatch()也是从基类COleDispatchDriver继承的。4.2 数据交换无论是采用哪种调用方式,Client都需要一种中间数据类型来与Matlab交互数据。当要把参数传递给Matlab时,Client需要先把自己的数据转换成中间类型;当从Matlab获取结果时,Client要从中间类型中提取原始数据。对引擎库来说,这种中间类型是mxArray;对自动化服务器来说,这种中间类型是VARIANT。下面通过代码来说明这两种方式。4.2.1 引擎库使用引擎库的代码如下:double standard_deviation = 0;// Create a variable for our datamxArray *a = mxCreateDoubleMatrix(1, 20, mxREAL);& & & & mxArray *b = NULL;memcpy((void *)mxGetPr(a), (void *)Array, sizeof(Array));// Place the variable a into the MATLAB //workspaceengPutVariable(ep, &a&, a);& & & & & & & & // Evaluate functionengEvalString(ep, &b =std(a);&);& & & & // Get Resultb = engGetVariable(ep, &b&);& & & & & & & & standard_deviation = mxGetPr(b)[0];cout && &The standard deviation is & && standard_deviation &&// Release memorymxDestroyArray(a);a= NULL;mxDestroyArray(b);b= NULL;4.2.2 自动化服务器使用自动化服务器的代码如下:double standard_deviation = 0;VARIANT& & & & // 用于向Matlab传递参数VariantInit(&a);VARIANT& & & & // 用于从Matlab获得结果VariantInit(&b);VARIANT& & & & // 用于从b中得到所需结果VariantInit(&c);// 向a内写入数据a.vt = VT_ARRAY | VT_R8;SAFEARRAY *SAFEARRAYBOUND rgsabound[1];rgsabound[0].lLbound = 0;rgsabound[0].cElements = 20;psa = SafeArrayCreate(VT_R8, 1, rgsabound);a.parray =for(unsigned int i=0; i& rgsabound[0].cE i++)SafeArrayPutElement(a.parray, (long*)&i, &(Array[i]));//调用Matlab,函数Feval()为由Class Wizard //自动生成的Feval()的重载,原函数有过多//参数,多余参数均被赋予同一VT_EMPTY //类的VARIANT变量MatlabAuto.Feval(&std&, 1, &b, a);// 此时b.vt的值为C),即VT_A//RRAY(0x2000)与VT_VARIANT(0x000C)//按位相或的结果,所以获取结果时需要变//量cint& & & & j = 0;SafeArrayGetElement(b.parray, (long*)&j, &c);standard_deviation = c.dblVcout && &The standard deviation is & && standard_deviation &&//释放变量a、b的空间5 总结COM是Microsoft公司提供的提高应用互操作性能的接口,利用Matlab提供的两个COM接口――IEngine和IDispatch,在Matlab引擎库或MFC类COleDispatchDriver的帮助下,VC++程序可很轻松的在程序中使用Matlab丰富的函数和图形功能[2],从而加快程序的开发。但这需要Matlab环境的运行。除了Matlab engine library(引擎库)和COM Automation Server,Matlab对COM的支持还有MATLAB Builder for .NET。它可以根据编程人员的要求将一组M文件编译成可供其它支持COM语言调用的COM组件,VC++程序使用这些组件就可以脱离Matlab[3],但不是所有的Matlab函数都可以被编译。参考文献:[1] Shepherd G,Wingo S.MFC internals:inside the microsoft Foundation Class architecture[M].Reading,Mass:Addison-Ewsley,.[2] 赵启蒙,高美娟.通过面向对象编程调用MATLAB绘图的实现[J].大庆石油学院学报,):80-82.[3] 姚光强,陈立平.基于COM技术的C#与Matlab混合编程[J].计算机工程,):87-89.欢迎您转载分享:热门教育学习好评教育学习c#调用matlab函数(混合编程)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
c#调用matlab函数(混合编程)
详​细​介​绍​了​c​#​调​用​m​a​t​l​a​b​函​数​的​具​体​过​程​,​包​含​d​l​l​创​建​,​c​#​添​加​引​用​,​数​据​类​型​转​换​和​m​a​t​l​a​b​多​参​数​返​回​处​理​。
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢

我要回帖

更多关于 matlab调用函数 的文章

 

随机推荐