在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
C++调用Matlab,实在是不得已的方法。原文链接: http://kylen314.blog.com/2012/12/11/matlab_for_cplusplus/ 这是个很善良的博客,只出现了一个小小的错误! 内容:有少量修改! 噩耗啊噩耗啊!!!!最近本身就忙到吐,什么老板的专题研究,什么人脸性别识别,什么电功率分解算法研究,本身就快虚脱,然后昨天突然说一年半前申请的专利有个公式有点问题,我研究了半天也不知道一年半前的我为什么会写出那样的公式【囧】,然后昨天突然师兄跟我说,老板让我这周内搭出某个系统的演示平台,我勒个去,那个系统因为要从数字通信分析仪上获取数据,所以用NI公司的GPIB采集卡,驱动文件里面提供了C++的接口,然后之后数据我是用matlab处理的,必须妥妥的嘛,结果现在要搭个系统意味着采集和处理要继承在一起,我就怂了,我matlab里面调用了那么多计算方法不明的函数,要怎么移植到C++上啊,其实主要问题还是时间不够,时间充足什么都好说。。。 所以只好飞快研究C++怎么调用matlab的函数了。。。研究了一下,方法好像很多,比如使用MATLAB Engine,它可以在C++里面调用直接使用matlab的函数,但是对于我这个系统,最好可以直接调用整个matlab的function,虽然MATLAB Engine我不知道可不可以,没深究,后来研究了另外一个方法。总结一下当备忘。。 系统配置:环境变量path中要加入matlab的bin目录:即加上X:/XXXXXX/MATLAB/R2009a/bin/win32 虽然,我发现好像装完matlab就已经自动加上了。。。 C++编译器配置:不管用VS也好,还是VC6.0也好,VC6中是打开Tool→Options→Directories,VS中是打开Tool→Options→Project and Solution→VC++ Directories,然后添加以下东西:
这样C++端就完成配置了。 Matlab的配置:
配置完上面的东西,就可以了~
C++调用matlab使用方法:
C++代码编写:文件一开始要添加lib文件,代码如下: #pragma comment(lib,"libdflapack.lib") #这个文件在2010a里面找不到,要去掉 #pragma comment(lib,"libemlrt.lib") #pragma comment(lib,"libeng.lib") #pragma comment(lib,"libfixedpoint.lib") #pragma comment(lib,"libmat.lib") #pragma comment(lib,"libmex.lib") #pragma comment(lib,"libmwlapack.lib") #pragma comment(lib,"libmwservices.lib") #pragma comment(lib,"libmx.lib") #pragma comment(lib,"libut.lib") #pragma comment(lib,"mclcommain.lib") #pragma comment(lib,"mclmcr.lib") #pragma comment(lib,"mclmcrrt.lib") 注意一下倒数第三个,据说matlab后面的版本是mclcommain.lib,之前的版本是mclco.lib,没考证,出了问题你去之前添加的lib路径下看一下就知道了。 然后添加你自己刚刚生成的lib文件 #pragma comment(lib,"XXX.lib")
之后必然要包含你自己的头文件啦。。 #include "XXX.h"
至于怎么用那些函数,简单说明一下,首先声明一下,下文中提到的XXX都是你在上面第五步中写的工程名,也就是上面lib和.h的XXX一样。 调用之前要先初始化,即调用函数: XXXInitialize();
经过试验,上面那个函数的运行之间极其之长。。。 当然,在结束调用,或者在程序的尾部要调用: XXXTerminate();
调用函数呢,就是你m文件的函数名,对了,众所周知m文件的文件名要和m文件里面的函数名一样,但是m文件的函数名不一定要和这里设置的Project一样,比如说函数名叫myfunction(),而工程名叫test,那么你生成的就是test.h,test.dll,test.lib,但是你在C++代码里面调用的时候用的却是myfunction。 如果你的myfunction没有输入输出参数,那么调用的时候就直接写myfunction()就可以了,如果有输入输出参数,函数调用格式是: myfunction(int nargout, mwArray& matrix...,const mwArray& n1....); 直接理解就是输出参数个数nargout 然后nargout个输出参数,数据类型是mwArray,稍有常识的人只要看到函数调用里面有&就基本是输出参数啦~ 然后就是各个输入参数,数据类型也是mwArray,看到const就知道应该是输入参数啦~ 啥?你问我为什么不用写输入参数个数,好好复习matlab函数去!!! 关于mwArray:这个是matlab生成的dll的接口数据类型,这个看上面的函数调用你就应该清楚这一点了,定义在matlab安装目录下的extern/include/下的mclcppclass.h下,有兴趣的自己看去~ 虽然还有一种数据类型是mxArray,但是不推荐使用,而且mwArray本身就是对mxArray的封装!不推荐使用是因为它的内存管理方式不好,而且使用的时候要用指针,而mwArray你可以直接作为对象来操作。【如果要生成接口为mxArray的dll的话,也可以在matlab命令行里面使用申明,但都说了。。不推荐。。】 matlab里面不特别说明数据类型都是double,但是在这里定义一个mwArray数据的时候要说明类型,定义方法如下: mwArray matrix(2,2,mxDOUBLE_CLASS); mwArray matri2(1,m,mxINT8_CLASS); 如果要赋值或者读取,方法如下: mwArray matrix(1,4,mxDOUBLE_CLASS); double a[] = {1,2,3,4}; matrix.SetData(a,4); cout<<matrix(1,2)<<endl; double *b = new double[4]; matrix.GetData(b,4); cout<<b[0]; 可能出现的问题:C++调用matlab生成的lib的时候可能会出现runtime error R6034的错误,虽然你可以关掉这个错误,程序可以继续跑,完全不碍事儿~但是也很烦,官方给出的说法是这样子的: SummaryOn Windows (XP or Vista) error R6034 is thrown by C runtime. DescriptionOn Windows (XP or Vista) error R6034 is thrown by the C runtime. This happens when executing standalone applications, C or C++ user applications built using C or C++ shared libraries, MATLAB Builder JA components, and MATAB Builder NE components. In this case, the user has a PATH directory containing msvcr80.dll. The error is thrown because the version of tbbmalloc.dll in mcrinstallroot|matlabroot\bin\arch does not contain a manifest. WorkaroundFor standalone executables and C/C++ shared libraries using a supported Microsoft Visual Compiler:
For standalone executables and C/C++ shared libraries Using Lcc-win32 compiler:
For MATLAB Builder for JA and MATLAB Builder for NE, perform the following on your development machine:
FixFor R2009b, a new version of tbbmalloc.dll is distributed that contains a manifest. Attachments但是这个问题也不一定会发生,我在我电脑上跑的时候出现了这个问题,但是在另一台新装matlab的电脑上就没出现,也许和网上传言的一样,重装一下就可以了。。不过好麻烦的说。。。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论