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,然后添加以下东西:

  1. Include Files里面添加X:/XXXXXX/MATLAB/R2009a/extern/include
  2. Include Files里面添加X:/XXXXXX/MATLAB/R2009a/extern/include/win32
  3. Library Files里面添加X:/XXXXXX/MATLAB/R2009a/extern/lib/win32/microsoft

这样C++端就完成配置了。

Matlab的配置:

  1. 命令行中输入mbuild -setup,第一个选y,第二个选你的编译器,VS或者VC6.0对应的号码,一般是2,第三个再选y
  2. 命令行中输入mex -setup,选项和第一步一样。
配置完上面的东西,就可以了~

C++调用matlab使用方法:

  1. 首先写一个正确的matlab的m文件并保存,【额,不正确的我没试过。。】比如说是functin [a b] = function_name(c,d)
  2. matlab命令行中输入deploytool
  3. 在Deployment Tool左上角点击Create a new deployment project
  4. 选择Matlab Compiler中的C++ Share Library
  5. 并在下面输入你的Project名字和路径
  6. 右键Add files加入你之前写的m文件
  7. 点击Build the Project即可完成编译。
  8. 在你选择的Project的路径下有两个文件夹,distrib和src,src那个不用管,打开distrib
  9. 里面有三个文件是你要用的,.dll和.lib和.h文件
  10. 建立你的C++工程,并将上一步中的三个文件加入到你的C++工程中即可。

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的错误,虽然你可以关掉这个错误,程序可以继续跑,完全不碍事儿~但是也很烦,官方给出的说法是这样子的:

Summary

On Windows (XP or Vista) error R6034 is thrown by C runtime.

Description

On 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.

Workaround

For standalone executables and C/C++ shared libraries using a supported Microsoft Visual Compiler:

  1. Download the zip files in the attachment. New option files have been provided for both 32-bit and 64-bit Windows. These new options files create executables with manifests which the operating system uses to locate runtime shared libraries in the Windows
    side X side area. Applications created using the attached options files can be distributed to deployed machines without any change to the target MCR install area.
  2. Back up matlabroot\bin\arch\mbuildopts by executing the following at the system command prompt: cd matlabroot\bin\arch & mkdir mbuildopts.bak & cd mbuildopts & copy *.*..\mbuildopts.bak where matlabroot is
    the MATLAB installation directory which can be found by typing: matlabroot at the MATLAB command prompt and arch is the platform.
  3. Unzip either options_win32.zip or options_win64.zip to the root of your MATLAB installation directory.
  4. Execute mbuild -setup.
  5. Rebuild your application using the downloaded options files which you enabled by executingmbuild -setup.

For standalone executables and C/C++ shared libraries Using Lcc-win32 compiler:

  1. Create a manifest file named application_name.exe.manifest (if creating an executable) orapplication_name.dll.manifest (if creating a shared library) with the following content:

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?> 
    <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> 
    <dependency> 
    <dependentAssembly> 
    <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.762' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> 
    </dependentAssembly> 
    </dependency> 
    </assembly>

    You can create this manifest file by copying the above content into a text file.

  2. Place the manifest in the same folder as the executable. For example, if you have an application called matrixdriver.exe, you would create a manifest file calledmatrixdriver.exe.manifest and put it in the same folder as the application.

For MATLAB Builder for JA and MATLAB Builder for NE, perform the following on your development machine:

  1. Change your folder to matlabroot\bin\arch
  2. Backup tbbmalloc.dll and rename it to tbbmalloc.dll.bak
  3. Execute the following command at a Visual Studio Command Prompt: mt.exe -inputresource:libut.dll;#2 -outputresource:tbbmalloc.dll;#2
  4. tbbmalloc.dll now contains a manifest, and must be distributed to any machine on which you have encountered error R6034 when executing a MATLAB Builder JA or MATLAB Builder NE component. You should place the modified tbbmalloc.dll in mcrroot\bin\arch where mcrroot is
    the MATLAB Compiler Runtime (MCR) installation directory.

Fix

For R2009b, a new version of tbbmalloc.dll is distributed that contains a manifest.

Attachments

但是这个问题也不一定会发生,我在我电脑上跑的时候出现了这个问题,但是在另一台新装matlab的电脑上就没出现,也许和网上传言的一样,重装一下就可以了。。不过好麻烦的说。。。

C++调用matlab编程的更多相关文章

  1. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

  2. 【环境】VS2013和MATLAB相互调用混合编程

    Visual Studio和MATLAB混合编程,有两种方法: 1 MATLAB调用C程序: 2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能): 前一 ...

  3. Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)

    原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...

  4. java调用matlab函数

    如何将实验结果在matlab中可视化呢,下面使用java语言编程,调用matlab中的函数: 本人安装的是Matlab7.11.0 (R2010a)和 Eclipse 4.2 : 1)首先设置环境变量 ...

  5. MATLAB 编程风格指南及注意事项

    MATLAB编程风格指南Richard Johnson 著Genial 译MATLAB 编程风格指南Richard JohnsonVersion 1.5,Oct. 2002版权: Datatool 所 ...

  6. vs 2010调用matlab dll显示窗口核心代码

    matlab代码: figure('NumberTitle','off','menubar','none','toolbar','none','name','Topo Image'); x=0:pi/ ...

  7. 3D Slicer中文教程(六)—调用matlab函数(MatlabBridge使用方法)

    1.安装MatlabBridge插件 (1)在工具栏找到Extension,点击进入Extension Manager (2)找到MatlabBridge,安装 2.配置MATLAB环境 (1)在模块 ...

  8. C++调用matlab函数

    C++与matlab混合编程——C++调用MATLAB函数 笔者最近在从事一个MFC相关的项目,要求将用Matlab实现的算法通过应用MFC制作成一个小应用.其中有一部分内容需要求一个多元函数的最值. ...

  9. VS2015调用matlab Plot函数

    最近经常采用Matlab仿真,然后C语言实现,最后需要将计算结果使用Qt的qwt或者matlab中的plot函数绘图. 因此想借用matlab的plot函数接口,使用VS2015来编写信号处理代码,最 ...

随机推荐

  1. 设置快捷键用sublime直接打开浏览器

    1.安装sidebarenhancements插件 ctrl+shift+p —> Install Package —> 找到SideBarEnhancements 2.配置预览快捷键 / ...

  2. 简述synchronized和java.util.concurrent.locks.Lock的异同

    1.synchronized 用在方法和代码块的区别? a. 可以只对需要同步的使用 b.与wait(),notify()和notifyall()方法使用比较方便 2.wait() a.释放持有的对象 ...

  3. ExtJs之Ext.grid.GridPanel(部分未完)

    今天在家休息,年假不用就作费啊. 看了几部香港老电影,陪爸爸看了勇士占奇才, 然后,测试了一下EXTJS未完的内容, 在京东上订了七本历史普及书,近两百块..:) 搞定. <!DOCTYPE h ...

  4. 修改oracle客户端的字符集

    客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter, 表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表 方法有 : ...

  5. [WPF]c#调用默认浏览器打开网址

    //调用系统默认的浏览器 System.Diagnostics.Process.Start("http://www.zhaokeli.com");

  6. C#之打印乘法表

    设计说明 由图可知: 1.我们需要打印出九行: 2.每行中最大列数等于行数: 代码实现 public void Display1() { Console.WriteLine("乘法表:&qu ...

  7. spring之注解(一)概述

    Spring的核心是依赖注入(DI),而依赖注入的基础是依赖信息的配置.这些配置称之为元数据. 在之前的的学习中.一直採用的是基于xml的配置,这些元数据配置在spring内部被注冊成为BeanDef ...

  8. struts1——静态ActionForm与动态ActionForm

    在struts1中,我们能够使用ActionForm来获取从client端提交上来的数据.并通过action配置中的name属性.将某个ActionForm配置到某次请求应答的Action中.作为本次 ...

  9. Android ListView拉到顶/底部,像橡皮筋一样弹性回弹复位

     <Android ListView拉到顶/底部,像橡皮筋一样弹性回弹复位> Android本身的ListView拉到顶部或者底部会在顶部/底部边缘间隙出现一道"闪光&quo ...

  10. 安卓欢迎界面和activity之间的跳转问题

    使用安卓的UI界面,就不得不了解activity,由于actvity就像是一个form表单一样,全部的UI都呈如今这里,他能够承载全部的UI控件. INtent就是一个中继站一样.他负责组件之间的沟通 ...