精华内容
下载资源
问答
  • VC中调用MATLAB

    2010-04-02 13:02:36
    VC中调用MATLABVC中调用MATLABVC中调用MATLAB
  • VC中调用Matlab的学习

    2012-08-11 21:19:29
    VC中调用Matlab的学习,详细介绍了VC中如何调用matlab,望对大家有帮助
  • visual c++ VC中调用MATLAB示例代码.zip
  • VC中调用MATLAB的5个例子 learn through example is very common and express for beginner,god bless you my griend!
  • VC中调用MATLAB的M文件的方法,描述了几种在VC中使用M文件的方式,适合初学者使用。
  • VC中调用matlab函数

    2010-10-11 21:47:00
    VC中调用matlab函数 <br />Visual C++是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快。但在科学计算方面函数库显得不够丰富、读取、显示数据图形不方便。Matlab是一款将数值分析...

    VC中调用matlab函数


    Visual C++是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快。但在科学计算方面函数库显得不够丰富、读取、显示数据图形不方便。Matlab是一款将数值分析、矩阵计算、信号处理和图形显示结合在一起,包含大量高度集成的函数可供调用,适合科学研究、工程设计等众多学科领域使用的一种简洁、高效的编程工具。不过由于Matlab使用的是解释性语言,大大限制了它的执行速度和应用场合。基于VC和Matlab混合编程是很多熟悉VC++编程而又需要进行科学计算、数据仿真的科研人员常用的一种方式,其中最简单也最直接的方法就是调用Matlab引擎。本文以下部分将详细介绍通过VC++6.0调用Matlab6.5引擎来达到VC++与Matlab数据共享编程的方法。

      1. 什么是Matlab引擎

      所谓Matlab引擎(engine),是指一组Matlab提供的接口函数,支持C/C++、Fortran等语言,通过这些接口函数,用户可以在其它编程环境中实现对Matlab的控制。可以主要功能有:

      ★ 打开/关闭一个Matlab对话;

      ★ 向Matlab环境发送命令字符串;

      ★ 从Matlab环境中读取数据;

      ★ 向Matlab环境中写入数据。

      与其它各种接口相比,引擎所提供的Matlab功能支持是最全面的。通过引擎方式,应用程序会打开一个新的Matlab进程,可以控制它完成任何计算和绘图操作。对所有的数据结构提供100%的支持。同时,引擎方式打开的Matlab进程会在任务栏显示自己的图标,打开该窗口,可以观察主程序通过engine方式控制Matlab运行的流程,并可在其中输入任何Matlab命令。

      实际上,通过引擎方式建立的对话,是将Matlab以ActiveX控件方式启动的。在Matlab初次安装时,会自动执行一次:

    matlab /regserver

      将自己在系统的控件库中注册。如果因为特殊原因,无法打开Matlab引擎,可以在Dos命令提示符后执行上述命令,重新注册。

      2. 配置编译器

      要在VC中成功编译Matlab引擎程序,必须包含引擎头文件engine.h并引入Matlab对应的库文件libmx.lib、libmat.lib、libeng.lib。具体的说,打开一个工程后,做如下设置(以VC6为例):

      1) 通过菜单工程/选项,打开设置属性页,进入Directories页面,在目录下拉列表框中选择Include files,添加路径:"C:/matlab/extern/include"(假定matlab安装在C:/matlab目录)。

      2) 选择Library files,添加路径:C:/matlab/extern/lib/win32/microsoft/msvc60。

      3) 通过菜单工程/设置,打开工程设置属性页,进入Link页面,在Object/library modules编辑框中,添加文件名libmx.lib libmat.lib libeng.lib。

      以上步骤1)、2)只需设置一次,而步骤3)对每个工程都要单独设定,对于其它C++编译器如Borland C++ Builder,设置大体相同,不再赘述。

      3. 引擎API详解

      在调用Matlab引擎之前,首先应在相关文件中加入一行:#include "enging.h",该文件包含了引擎API函数的说明和所需数据结构的定义。可以在VC中调用的引擎函数分别如下:

      3.1 引擎的打开和关闭

      engOpen-打开Matlab engine

      函数声明:

    Engine *engOpen(const char *startcmd);

      参数startcmd是用来启动Matlab引擎的字符串参数,在Windows操作系统中只能为NULL。

      函数返回值是一个Engine类型的指针,它是在engine.h中定义的engine数据结构。

      EngClose-关闭Matlab 引擎

      函数声明:

    int engClose(Engine *ep);

      参数ep代表要被关闭的引擎指针。

      函数返回值为0表示关闭成功,返回1表示发生错误。

      例如,通常用来打开/关闭Matlab引擎的代码如下:

    Engine *ep; //定义Matlab引擎指针。
    if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。
    {
    MessageBox("Can't start Matlab engine!" );
    exit(1);
    }
    . …………
    engClose(ep); //关闭Matlab引擎。

      3.2 向Matlab发送命令字符串

      engEvalString-发送命令让Matlab执行。

      函数声明:

    int engEvalString(Engine *ep, Const char *string);

      参数ep为函数engOpen返回的引擎指针,字符串string为要matlab执行的命令。

      函数返回值为0表示成功执行,返回1说明执行失败(如命令不能被Matlab正确解释或Matlab引擎已经关闭了)。

      3.3 获取Matlab命令窗口的输出

      要在VC中获得函数engEvalString发送的命令字符串被Matlab执行后在matlab窗口中的输出,可以调用engOUtputBuffer函数。

      函数声明:

    int engOutputBuffer(Engine *ep, char *p, int n);

      参数ep为Matlab引擎指针,p为用来保存输出结构的缓冲区,n为最大保存的字符个数,通常就是缓冲区p的大小。该函数执行后,接下来的engEvalString函数所引起的命令行输出结果会在缓冲区p中保存。如果要停止保存,只需调用代码:engOutputBuffer(ep, NULL, 0)。

      3.4 读写Matlab数据

      3.4.1从Matlab引擎工作空间中获取变量。

    mxArray *engGetVariable(Engine *ep, const char *name);

      参数ep为打开的Matlab引擎指针,name为以字符串形式指定的数组名。

      函数返回值是指向name数组的指针,类型为mxArray*(mxArray数据类型在本文第4节详细简介)。

      3.4.2 向Matlab引擎工作空间写入变量。

    int engPutVariable(Engine *ep, const char *name, const mxArray *mp);

      参数ep为打开的Matlab引擎指针,mp为指向被写入变量的指针,name为变量写入后在Matlab引擎工作空间中的变量名。
    函数返回值为0表示写入变量成功,返回值为1表示发生错误。

      3.5 调用引擎时显示/隐藏Matlab主窗口

      默认情况下,以engine方式调用Matlab的时候,会打开Matlab主窗口,可在其中随意操作。但有时也会干扰应用程序的运行,可用以下设置是否显示该窗口。

    int engSetVisible(Engine *ep, bool value);

      参数ep为打开的Matlab引擎指针,value为是否显示的标志,取值true(或1)表示显示Matlab窗口,取值false(或0)表示隐藏Matlab窗口。

      函数返回值为0表示设置成功,为1表示有错误发生。

      要获得当前Matlab窗口的显示/隐藏情况,可以调用函数:

    int engGetVisible(Engine *ep, bool *value);

      参数ep为打开的Matlab引擎指针,Value为用来保存显示/隐藏情况的变量(采用指针方式传递)。

      函数返回值为0表示获取成功,为1表示有错误发生。
    4. 数据类型mxArray的操作

      在上节的Matlab引擎函数中,所有与变量有关的数据类型都是mxArray类型。数据结构mxArray以及大量的mx开头的函数,广泛用于Matlab 引擎程序和Matlab C数学库中。mxArray是一种很复杂的数据结构,与Matlab中的array相对应,我们只需熟悉Matlab的array类型和几个常用的mxArray函数即可。

      在VC中,所有和Matlab的数据交互都是通过mxArray来实现的,在使用mxArray类型的程序中,应包含头文件matrix.h,不过在引擎程序中,一般会包含头文件engine.h,该文件里面已经包含了matrix.h,因此无需重复包含。

      4.1 创建和清除mxArray型数据

      Matlab有很多种变量类型,对应于每种类型,基本上都有一个函数用于创建,但它们都有相同的数据结构,就是mxArray。

      数组的建立采用mxCreatexxx形式的函数,例如新建一个double类型数组,可用函数mxCreateDoubleMatrix,函数形式如下:

    mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag);

      参数m和n为矩阵的函数和列数。ComplexFlag为常数,用来区分矩阵中元素是实数还是复数,取值分别为mxREAL和mxCOMPLEX。

      例如,创建一个3行5列的二维实数数组,可用如下语句:

    mxArray *T = mxCreateDoubleMatrix(3, 5, mxREAL);

      对应的,要删除一个数组mxDestroyArray,该函数声明如下:

    void mxDestroyArray(mxArray *array_ptr);

      参数array_ptr为要删除的数组指针。

      例如,要删除上面创建的数组T,可用如下语句:

    mxDestroyArray(T);

      类似的创建函数还有:

    mxArray *mxCreateString(const char *str);

      创建一个字符串类型并初始化为str字符串。

      一般的在VC与Matlab交互中,以上两种类型就够了,其它类型数组的创建这里不再介绍。

      4.2 管理mxArray数据类型

      4.2.1 管理mxArray数据大小

      要获得mxArray数组每一维上元素的个数,可以用mxGetM和mxGetN函数。其中mxGetM用来获得数组第一维的元素个数,对于矩阵来说就是行数。

    int mxGetM(const mxArray *array_ptr); //返回array_ptr对应数组第一维的元素个数(行数)
    int mxGetN(const mxArray *array_ptr); //返回array_ptr对应数组其它维的元素个数,对于矩阵来说是列数。对于多维数组来说是从第2维到最后一维的各维元素个数的乘积。

      要获得某一特定维的元素个数,则要用函数:

    const int *mxGetDimensions(const mxArray *array_ptr);

      该函数返回array_ptr各维的元素个数保存在一个int数组中返回。对于常用的矩阵来说,用mxGetM和mxGetN两个函数就可以了。

      另外还可以通过mxGetNumberOfDimensions来获得数组的总的维数,用mxSetM、mxSetN设置矩阵的行数和列数,函数说明如下:


    mxGetNumberOfDimensions(const mxArray *array_ptr); //返回数组的维数
    void mxSetM(mxArray *array_ptr, int m); //设置数组为m行
    void mxSetN(mxArray *array_ptr, int n); //设置数组为n列


      4.2.2 判断mxArray数组类型

      在对mxArray类型的变量进行操作之前,可以验证以下其中的数组的数据类型,比如是否为double数组、整数、字符串、逻辑值等,以及是否为某种结构、类、或者是特殊类型,比如是否为空数组,是否为inf、NaN等。常见的判断函数有:

    bool mxIsDouble(const mxArray *array_ptr);
    bool mxIsComplex(const mxArray *array_ptr);
    bool mxIsChar(const mxArray *array_ptr);
    bool mxIsEmpty(const mxArray *array_ptr);
    bool mxIsInf(double value);
    …… ……

      这些函数比较简单,意义自明,不再解释。

      4.2.3 管理mxArray数组的数据

      对于常用的double类型的数组,可以用mxGetPr和mxGetPi两个函数分别获得其实部和虚部的数据指针,这两个函数的声明如下:

    double *mxGetPr(const mxArray *array_ptr); //返回数组array_ptr的实部指针
    double *mxGetPi(const mxArray *array_ptr); //返回数组array_ptr的虚部指针

      这样,就可以通过获得的指针对mxArray类型的数组中的数据进行读写操作。例如可以用函数engGetVariable从Matlab工作空间读入mxArray类型的数组,然后用mxGetPr和mxGetPi获得数据指针,对并其中的数据进行处理,最后调用engPutVariable函数将修改后的数组重新写入到Matlab工作空间。具体实现见第5节程序实例。

    5. 程序实例

      对大部分软件研发人员来说利用VC编程方便、高效,但是要显示数据图形就不那么容易了,这时候不防借助Matlab引擎辅助画图做数据分析。下面通过实例演示如何利用VC调用Matlab绘图,程序的主要功能是在VC中对数组x计算函数值y=sin(x) ±log(x),然后调用Matlab绘制y对x的图形。

      在VC中新建工程,编写代码如下:

    #include <iostream>
    #include <math.h>
    #include "engine.h"
    using namespace std;
    void main()
    {
     const int N = 50;
     double x[N],y[N];
     int j = 1;
     for (int i=0; i<N; i++) //计算数组x和y
     {
      x[i] = (i+1);
      y[i] = sin(x[i]) + j * log(x[i]); //产生-之间的随机数赋给xx[i];
      j *= -1;
     }
     Engine *ep; //定义Matlab引擎指针。
     if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。
     {
      cout <<"Can't start Matlab engine!" <<endl;
      exit(1);
     }

     //定义mxArray,为行,N列的实数数组。
     mxArray *xx = mxCreateDoubleMatrix(1,N, mxREAL);
     mxArray *yy = mxCreateDoubleMatrix(1,N, mxREAL); //同上。

     memcpy(mxGetPr(xx), x, N*sizeof(double)); //将数组x复制到mxarray数组xx中。
     memcpy(mxGetPr(yy), y, N*sizeof(double)); //将数组x复制到mxarray数组yy中。

     engPutVariable(ep, "xx",xx); //将mxArray数组xx写入到Matlab工作空间,命名为xx。
     engPutVariable(ep, "yy",yy); //将mxArray数组yy写入到Matlab工作空间,命名为yy。

     //向Matlab引擎发送画图命令。plot为Matlab的画图函数,参见Matlab相关文档。
     engEvalString(ep, "plot(xx, yy); ");

     mxDestroyArray(xx); //销毁mxArray数组xx和yy。
     mxDestroyArray(yy);

     cout <<"Press any key to exit!" <<endl;
     cin.get();
     engClose(ep); //关闭Matlab引擎。
    }


    6. 小结

      本文详细的介绍了Matlab引擎使用方法并演示了一个简单的利用VC调用Matlab画图的程序实例。大多数时候,程序员可以利用Matlab强大的数据读写、显示能力和VC编程的高效率。例如,在Matlab中要读入一幅任意格式的图像均只需一条命令i=imread('test.jp');图像数据矩阵便存放在了二维数组i中,可以通过VC读入该数组进行相关处理再调用Matlab显示,这种混合编程方式能大大提高工作效率。

      当然,利用VC编译的Matlab引擎程序,运行环境中还必须Matlab的支持,如果要编译完全脱离Matlab的程序,可采用其它方式,如利用第三方Matcom程序编译独立的可执行程序等
     


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fengqiao1999/archive/2010/03/21/5401201.aspx

    展开全文
  • matlab中把程序编译成DLL,然后在vc中调用
  • VC中调用matlab引擎

    2012-05-10 14:50:38
    1. 包含和库目录,还有附加依赖项都选好 ... // matlab engine 4. 加上openEng和closeEng  void open_matEng()  { if( !( ep = engOpen(NULL) ) ) { fprintf(stderr, "\nCan't start MATLAB engine\n")

    1. 包含和库目录,还有附加依赖项都选好

    2. #include<engine.h>

    3. 定义Engine *ep; // matlab engine

    4. 加上openEng和closeEng

     void open_matEng() 
    {
    if( !( ep = engOpen(NULL) ) )
    {
    fprintf(stderr, "\nCan't start MATLAB engine\n");
    exit( EXIT_FAILURE );
    }
    engSetVisible( ep , true) ;
    engEvalString( ep , "clear" ) ;
    }


    void close_matEng()
    {
    // engSetVisible(ep,false);
    engEvalString(ep,"clear");
    // engClose(ep);
    }

    展开全文
  • 文章来源: laputa_新浪博客 为了实现从VC调用MATLAB的神经网络工具箱,最近这两天可谓是折腾了好一阵子。好在最终总算是把它给搞定了,不妨在此做个小结,希望对遇到同样问题的同学能起到一定的借鉴作用。 我所...

    文章来源: laputa_新浪博客

       为了实现从VC调用MATLAB的神经网络工具箱,最近这两天可谓是折腾了好一阵子。好在最终总算是把它给搞定了,不妨在此做个小结,希望对遇到同样问题的同学能起到一定的借鉴作用。

       我所采用的方法是利用matlab中的deploytool命令将写好的m函数(该函数的主要功能是使用神经网络工具箱来实现一个简单机器学习算法)编译成C++的动态链接库,然后再VC中调用。虽然原理说起来简单,可做起来却颇不顺利,先后遇到了一系列问题: 

    一、无法识别编译器

       我最初使用的软件版本是matlab R2009a及vc2008,首先遇到的第一个问题是在matlab中使用mbuild -setup命令对matlab compile进行配置时,出现了如下结果:

     Please choose your compiler for building standalone MATLAB applications:

     Would you like mbuild to locate installed compilers [y]/n? y

     [1] Lcc-win32 C 2.4.1 in D:\PROGRA~1\matlab\r2008b\sys\lcc

     [0] None

       简单来说就是无法识别已安装的VC2008的编译器。后来通过在Matlab中文论坛中查阅相关资料,用如下方法解决了该问题:

    >> mbuild -setup
    Please choose your compiler for building standalone MATLAB applications:

    Would you like mbuild to locate installed compilers [y]/n? n
    Select a compiler:
    [1] Lcc-win32 C 2.4.1
    [2] Microsoft Visual C++ 6.0
    [3] Microsoft Visual C++ .NET 2003
    [4] Microsoft Visual C++ 2005 SP1
    [5] Microsoft Visual C++ 2008 Express
    [6] Microsoft Visual C++ 2008 SP1
    [0] None
    Compiler: 6
    The default location for Microsoft Visual C++ 2008 SP1 compilers is C:\Program Files\Microsoft Visual Studio 9.0,
    but that directory does not exist on this machine.  
    Use C:\Program Files\Microsoft Visual Studio 9.0 anyway [y]/n? n

    Please enter the location of your compiler: [C:\Program Files\Microsoft Visual Studio 9.0] D:\Program Files\Microsoft Visual Studio 9.0 
    Please verify your choices:
    Compiler: Microsoft Visual C++ 2008 SP1  
    Location: D:\Program Files\Microsoft Visual Studio 9.0
    Are these correct [y]/n? y

       按照别人的说法,出现这一问题的原因有两个:一是先安装MATLAB再安装Visual Studio;二是Visual Studio没有安装在默认路径。不过我后来的实验证明,即使我先在默认路径安装VC2008,再安装MATLAB R2007b,在MATLAB中仍然无法识别出VC的编译器,此乃后话。    

    二、运行时错误

       按照网上的教程,我利用deploytool编译出了m函数相对应的三个文件:*.lib,*.h及*.dll,将其加入到新建立的C++工程(Win32 Console)中,并在项目属性及IDE的选项中做好相关配置。但运行到MCR的初始化函数部分mclInitializeApplication(NULL,0),就出现了RunTime Error的错误。

    由于是在Matlab Component Runtime上出现的问题,我只好尝试着安装MCR环境,即运行<Matlab安装目录>\toolbox\compiler \deploy\win32里的MCRInstaller.exe文件。安装以后再次运行程序,这时候mclInitializeApplication(NULL,0)函数及接下来的dll库初始化函数均可以正常运行,但在函数调用的时候又一次出现了RunTime Error的错误:“R6034, an application has made an attempt to load the C runtime library incorrectly.”此时还不能够关闭错误警告窗,整个VC处于假死状态,得从任务管理器中强行终止。

    难道是因为编译的m文件比较复杂,调用到了一些有图形界面显示的函数?为此,我重新做了一个测试,该测试中所调用到的m函数只是实现了矩阵相加的功能。运行之后发现仍然会出现RunTime Error的错误警告窗,只不过此时该警告窗口能够被关闭,而程序还是可以得到正确的结果。

       网上搜寻无解,我继续尝试着将已有的VC2008和MATLAB R2009a卸载,重新将VC2008安装在默认的路径C:\Program Files\Microsoft Visual Studio 9.0,安装MATLAB的较低级版本R2008b,并且将之前安装的7.10版本的MCR环境卸载掉,因为R2008b自带了7. 09版本的MCR。

    作了以上工作后,重新运行C++程序,那恼人的RunTime Error总算不再出现了。将调用的m函数变得复杂些,加入了作图的plot命令,一切仍然正常。摸索到现在,总算是看到了一点曙光。 

    三、无法调用神经网络工具箱中的相关命令

       现在开始编译我们最初的m代码,在C++中调用生成的dll,出现“undefined function or method 'newrb' for input arguments of type 'double”的错误信息。返回去查看m代码编译时产生的日志文件mccExcludedFiles.log,发现其中有这么一句:

    D:\Program Files\MATLAB\R2008b\toolbox\nnet\nnet\nnnetwork\newrb.m
      called by F:\HybridProgramming\MLA\depth_mapping.m
    (because of toolbox compilability rules)

    看起来像是matlab compile不支持对newrb命令的编译。

        为了证实这一点,我查找了MATLAB的官方论坛,管理员对一个遇到同样问题的人回答如下:

    You will not be able to compile any function which trains the network (like ADAPT). Though the link does not explicitly list these funcions (like ADAPT), they fall under the 'All other command line functionality'.

    However, you can deploy a M function code which uses a pre-trained network. I believe the SIM function will deploy fine.

    The workflow I see is:

    1. In MATLAB, train you network using test input/output

    2. Save the network (mat file?)

    3. Create a deployable function which then uses the pretrained network for new data. The network itself would not change/adapt/train in this function

    4. Compile and deploy the above function

        总之其主要意思就是说,MATLAB compile不支持对神经网络工具箱中涉及到训练的函数命令进行编译(像我所使用的newrb命令正是如此),只能编译那些用在已训练好的网络上的函数命令(例如SIM)

    这样看来,难道我只能使用MATLAB引擎法来调用神经网络的相关命令,都已经进行到现在,实在不甘心。抱着试一试的心态,我在MATLAB中使用deploytool命令新建一个C++ Shared Library的编译工程,并从MATLAB目录里将newrb.m文件拷贝了一份到当前的编译工程目录下,除了将我们希望调用的depth_mapping.m添加进编译工程的Exported functions目录,拷贝过来的newrb.m也被添加到Other files的目录,然后开始编译。

    最终,由这两个m文件所编译成的dll文件,居然在C++中调用成功。看到C++运行时弹出来的训练误差曲线图,觉得这两天总算没有白折腾。当然,有可能我的方法完全就是贻笑大方,在这里就权且算是抛砖引玉吧。

       需要一提的是,同样的配置,同样的MATLAB和VC版本,这种混合编程的方法在我vista的笔记本上却不能运行成功,连调试模式都无法进入,显示 STATUS_DLL_NOT_FOUND的错误,可MATLAB生成的dll文件明明都已经放在了运行程序的目录中了呀。究竟这是什么问题?还希望能有 这方面的编程高手多多指教。

    展开全文
  • 错误如图,按照教程做的,哪里错了呢?请高手指教!![图片说明](https://img-ask.csdn.net/upload/201512/16/1450272403_263469.png)
  • Matlab是一款将数值分析、矩阵计算、信号处理和图形显示结合在一起,包含大量高度集成的函数可供调用,适合科学研究、工程设计等众多学科领域使用的一种简洁、高效的编程工具。不过由于Matlab使用的是解释性语言,...

    Visual C++是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快。但在科学计算方面函数库显得不够丰富、读取、显示数据图形不方便。Matlab是一款将数值分析、矩阵计算、信号处理和图形显示结合在一起,包含大量高度集成的函数可供调用,适合科学研究、工程设计等众多学科领域使用的一种简洁、高效的编程工具。不过由于Matlab使用的是解释性语言,大大限制了它的执行速度和应用场合。基于VC和Matlab混合编程是很多熟悉VC++编程而又需要进行科学计算、数据仿真的科研人员常用的一种方式,其中最简单也最直接的方法就是调用Matlab引擎。本文以下部分将详细介绍通过VC++6.0调用Matlab6.5引擎来达到VC++与Matlab数据共享编程的方法。

      1. 什么是Matlab引擎

      所谓Matlab引擎(engine),是指一组Matlab提供的接口函数,支持C/C++、Fortran等语言,通过这些接口函数,用户可以在其它编程环境中实现对Matlab的控制。可以主要功能有:

      ★ 打开/关闭一个Matlab对话;

      ★ 向Matlab环境发送命令字符串;

      ★ 从Matlab环境中读取数据;

      ★ 向Matlab环境中写入数据。

      与其它各种接口相比,引擎所提供的Matlab功能支持是最全面的。通过引擎方式,应用程序会打开一个新的Matlab进程,可以控制它完成任何计算和绘图操作。对所有的数据结构提供100%的支持。同时,引擎方式打开的Matlab进程会在任务栏显示自己的图标,打开该窗口,可以观察主程序通过engine方式控制Matlab运行的流程,并可在其中输入任何Matlab命令。

      实际上,通过引擎方式建立的对话,是将Matlab以ActiveX控件方式启动的。在Matlab初次安装时,会自动执行一次:

    matlab /regserver

      将自己在系统的控件库中注册。如果因为特殊原因,无法打开Matlab引擎,可以在Dos命令提示符后执行上述命令,重新注册。

      2. 配置编译器

      要在VC中成功编译Matlab引擎程序,必须包含引擎头文件engine.h并引入Matlab对应的库文件libmx.lib、libmat.lib、libeng.lib。具体的说,打开一个工程后,做如下设置(以VC6为例):

      1) 通过菜单工程/选项,打开设置属性页,进入Directories页面,在目录下拉列表框中选择Include files,添加路径:"C:/matlab/extern/include"(假定matlab安装在C:/matlab目录)。

      2) 选择Library files,添加路径:C:/matlab/extern/lib/win32/microsoft/msvc60。

      3) 通过菜单工程/设置,打开工程设置属性页,进入Link页面,在Object/library modules编辑框中,添加文件名libmx.lib libmat.lib libeng.lib。

      以上步骤1)、2)只需设置一次,而步骤3)对每个工程都要单独设定,对于其它C++编译器如Borland C++ Builder,设置大体相同,不再赘述。

      3. 引擎API详解

      在调用Matlab引擎之前,首先应在相关文件中加入一行:#include "enging.h",该文件包含了引擎API函数的说明和所需数据结构的定义。可以在VC中调用的引擎函数分别如下:

      3.1 引擎的打开和关闭

      engOpen-打开Matlab engine

      函数声明:

    Engine *engOpen(const char *startcmd);

      参数startcmd是用来启动Matlab引擎的字符串参数,在Windows操作系统中只能为NULL。

      函数返回值是一个Engine类型的指针,它是在engine.h中定义的engine数据结构。

      EngClose-关闭Matlab 引擎

      函数声明:

    int engClose(Engine *ep);

      参数ep代表要被关闭的引擎指针。

      函数返回值为0表示关闭成功,返回1表示发生错误。

      例如,通常用来打开/关闭Matlab引擎的代码如下:

    Engine *ep; //定义Matlab引擎指针。
    if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。
    {
    MessageBox("Can't start Matlab engine!" );
    exit(1);
    }
    . …………
    engClose(ep); //关闭Matlab引擎。

      3.2 向Matlab发送命令字符串

      engEvalString-发送命令让Matlab执行。

      函数声明:

    int engEvalString(Engine *ep, Const char *string);

      参数ep为函数engOpen返回的引擎指针,字符串string为要matlab执行的命令。

      函数返回值为0表示成功执行,返回1说明执行失败(如命令不能被Matlab正确解释或Matlab引擎已经关闭了)。

      3.3 获取Matlab命令窗口的输出

      要在VC中获得函数engEvalString发送的命令字符串被Matlab执行后在matlab窗口中的输出,可以调用engOUtputBuffer函数。

      函数声明:

    int engOutputBuffer(Engine *ep, char *p, int n);

      参数ep为Matlab引擎指针,p为用来保存输出结构的缓冲区,n为最大保存的字符个数,通常就是缓冲区p的大小。该函数执行后,接下来的engEvalString函数所引起的命令行输出结果会在缓冲区p中保存。如果要停止保存,只需调用代码:engOutputBuffer(ep, NULL, 0)。

      3.4 读写Matlab数据

      3.4.1从Matlab引擎工作空间中获取变量。

    mxArray *engGetVariable(Engine *ep, const char *name);

      参数ep为打开的Matlab引擎指针,name为以字符串形式指定的数组名。

      函数返回值是指向name数组的指针,类型为mxArray*(mxArray数据类型在本文第4节详细简介)。

      3.4.2 向Matlab引擎工作空间写入变量。

    int engPutVariable(Engine *ep, const char *name, const mxArray *mp);

      参数ep为打开的Matlab引擎指针,mp为指向被写入变量的指针,name为变量写入后在Matlab引擎工作空间中的变量名。
    函数返回值为0表示写入变量成功,返回值为1表示发生错误。

      3.5 调用引擎时显示/隐藏Matlab主窗口

      默认情况下,以engine方式调用Matlab的时候,会打开Matlab主窗口,可在其中随意操作。但有时也会干扰应用程序的运行,可用以下设置是否显示该窗口。

    int engSetVisible(Engine *ep, bool value);

      参数ep为打开的Matlab引擎指针,value为是否显示的标志,取值true(或1)表示显示Matlab窗口,取值false(或0)表示隐藏Matlab窗口。

      函数返回值为0表示设置成功,为1表示有错误发生。

      要获得当前Matlab窗口的显示/隐藏情况,可以调用函数:

    int engGetVisible(Engine *ep, bool *value);

      参数ep为打开的Matlab引擎指针,Value为用来保存显示/隐藏情况的变量(采用指针方式传递)。

      函数返回值为0表示获取成功,为1表示有错误发生。
    4. 数据类型mxArray的操作

      在上节的Matlab引擎函数中,所有与变量有关的数据类型都是mxArray类型。数据结构mxArray以及大量的mx开头的函数,广泛用于Matlab 引擎程序和Matlab C数学库中。mxArray是一种很复杂的数据结构,与Matlab中的array相对应,我们只需熟悉Matlab的array类型和几个常用的mxArray函数即可。

      在VC中,所有和Matlab的数据交互都是通过mxArray来实现的,在使用mxArray类型的程序中,应包含头文件matrix.h,不过在引擎程序中,一般会包含头文件engine.h,该文件里面已经包含了matrix.h,因此无需重复包含。

      4.1 创建和清除mxArray型数据

      Matlab有很多种变量类型,对应于每种类型,基本上都有一个函数用于创建,但它们都有相同的数据结构,就是mxArray。

      数组的建立采用mxCreatexxx形式的函数,例如新建一个double类型数组,可用函数mxCreateDoubleMatrix,函数形式如下:

    mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag);

      参数m和n为矩阵的函数和列数。ComplexFlag为常数,用来区分矩阵中元素是实数还是复数,取值分别为mxREAL和mxCOMPLEX。

      例如,创建一个3行5列的二维实数数组,可用如下语句:

    mxArray *T = mxCreateDoubleMatrix(3, 5, mxREAL);

      对应的,要删除一个数组mxDestroyArray,该函数声明如下:

    void mxDestroyArray(mxArray *array_ptr);

      参数array_ptr为要删除的数组指针。

      例如,要删除上面创建的数组T,可用如下语句:

    mxDestroyArray(T);

      类似的创建函数还有:

    mxArray *mxCreateString(const char *str);

      创建一个字符串类型并初始化为str字符串。

      一般的在VC与Matlab交互中,以上两种类型就够了,其它类型数组的创建这里不再介绍。

      4.2 管理mxArray数据类型

      4.2.1 管理mxArray数据大小

      要获得mxArray数组每一维上元素的个数,可以用mxGetM和mxGetN函数。其中mxGetM用来获得数组第一维的元素个数,对于矩阵来说就是行数。

    int mxGetM(const mxArray *array_ptr); //返回array_ptr对应数组第一维的元素个数(行数)
    int mxGetN(const mxArray *array_ptr); //返回array_ptr对应数组其它维的元素个数,对于矩阵来说是列数。对于多维数组来说是从第2维到最后一维的各维元素个数的乘积。

      要获得某一特定维的元素个数,则要用函数:

    const int *mxGetDimensions(const mxArray *array_ptr);

      该函数返回array_ptr各维的元素个数保存在一个int数组中返回。对于常用的矩阵来说,用mxGetM和mxGetN两个函数就可以了。

      另外还可以通过mxGetNumberOfDimensions来获得数组的总的维数,用mxSetM、mxSetN设置矩阵的行数和列数,函数说明如下:


    mxGetNumberOfDimensions(const mxArray *array_ptr); //返回数组的维数
    void mxSetM(mxArray *array_ptr, int m); //设置数组为m行
    void mxSetN(mxArray *array_ptr, int n); //设置数组为n列


      4.2.2 判断mxArray数组类型

      在对mxArray类型的变量进行操作之前,可以验证以下其中的数组的数据类型,比如是否为double数组、整数、字符串、逻辑值等,以及是否为某种结构、类、或者是特殊类型,比如是否为空数组,是否为inf、NaN等。常见的判断函数有:

    bool mxIsDouble(const mxArray *array_ptr);
    bool mxIsComplex(const mxArray *array_ptr);
    bool mxIsChar(const mxArray *array_ptr);
    bool mxIsEmpty(const mxArray *array_ptr);
    bool mxIsInf(double value);
    …… ……

     

      这些函数比较简单,意义自明,不再解释。

      4.2.3 管理mxArray数组的数据

      对于常用的double类型的数组,可以用mxGetPr和mxGetPi两个函数分别获得其实部和虚部的数据指针,这两个函数的声明如下:

    double *mxGetPr(const mxArray *array_ptr); //返回数组array_ptr的实部指针
    double *mxGetPi(const mxArray *array_ptr); //返回数组array_ptr的虚部指针

     

      这样,就可以通过获得的指针对mxArray类型的数组中的数据进行读写操作。例如可以用函数engGetVariable从Matlab工作空间读入mxArray类型的数组,然后用mxGetPr和mxGetPi获得数据指针,对并其中的数据进行处理,最后调用engPutVariable函数将修改后的数组重新写入到Matlab工作空间。具体实现见第5节程序实例。

    5. 程序实例

      对大部分软件研发人员来说利用VC编程方便、高效,但是要显示数据图形就不那么容易了,这时候不防借助Matlab引擎辅助画图做数据分析。下面通过实例演示如何利用VC调用Matlab绘图,程序的主要功能是在VC中对数组x计算函数值y=sin(x) ±log(x),然后调用Matlab绘制y对x的图形。

      在VC中新建工程,编写代码如下:

    #include <iostream>
    #include <math.h>
    #include "engine.h"
    using namespace std;
    void main()
    {
     const int N = 50;
     double x[N],y[N];
     int j = 1;
     for (int i=0; i<N; i++) //计算数组x和y
     {
      x[i] = (i+1);
      y[i] = sin(x[i]) + j * log(x[i]); //产生-之间的随机数赋给xx[i];
      j *= -1;
     }
     Engine *ep; //定义Matlab引擎指针。
     if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。
     {
      cout <<"Can't start Matlab engine!" <<endl;
      exit(1);
     }

     //定义mxArray,为行,N列的实数数组。
     mxArray *xx = mxCreateDoubleMatrix(1,N, mxREAL);
     mxArray *yy = mxCreateDoubleMatrix(1,N, mxREAL); //同上。

     memcpy(mxGetPr(xx), x, N*sizeof(double)); //将数组x复制到mxarray数组xx中。
     memcpy(mxGetPr(yy), y, N*sizeof(double)); //将数组x复制到mxarray数组yy中。

     engPutVariable(ep, "xx",xx); //将mxArray数组xx写入到Matlab工作空间,命名为xx。
     engPutVariable(ep, "yy",yy); //将mxArray数组yy写入到Matlab工作空间,命名为yy。

     //向Matlab引擎发送画图命令。plot为Matlab的画图函数,参见Matlab相关文档。
     engEvalString(ep, "plot(xx, yy); ");

     mxDestroyArray(xx); //销毁mxArray数组xx和yy。
     mxDestroyArray(yy);

     cout <<"Press any key to exit!" <<endl;
     cin.get();
     engClose(ep); //关闭Matlab引擎。
    }


    6. 小结

      本文详细的介绍了Matlab引擎使用方法并演示了一个简单的利用VC调用Matlab画图的程序实例。大多数时候,程序员可以利用Matlab强大的数据读写、显示能力和VC编程的高效率。例如,在Matlab中要读入一幅任意格式的图像均只需一条命令i=imread('test.jp');图像数据矩阵便存放在了二维数组i中,可以通过VC读入该数组进行相关处理再调用Matlab显示,这种混合编程方式能大大提高工作效率。

      当然,利用VC编译的Matlab引擎程序,运行环境中还必须Matlab的支持,如果要编译完全脱离Matlab的程序,可采用其它方式,如利用第三方Matcom程序编译独立的可执行程序等

    展开全文
  • 现在我想用MFC做一个界面,添加一个打开按钮,选择一个txt文件,然后把这个txt文件的数据以图片方式显示出来,这里就要调用原来matlab写的函数了,我怎么样把他们连接起来??? matlab函数形式为: function ...
  • Visual Studio 2017 和 Matlab R2019a 按照网上介绍的方法在VS项目里进行配置: 设置好VS的include路径: 项目->属性->配置属性->VC++目录->包含目录,添加D:\MATLAB\R2019a\extern\include 设置好VS...
  •  很多人可能都有这样的疑惑,在用引擎调用matlab程序的时候,循环语句不起作用,如:  engEvalString(ep, " for ii=1:m");  engEvalString(ep, " for jj=1:n");  engEvalString(ep, " H(ii,jj)=1;"); ...
  • VC调用MATLAB

    2013-08-21 14:39:19
      在VC中使用CPen绘制宽度大于1的虚线   Matlab的函数及指令(转) VC中调用Matlab(转)  2012-01-03 14:59:06| 分类: Matlab | 标签: |字号大中小 订阅
  • vc调用matlab实例演示

    2011-05-24 18:54:07
    vc中调用matlab编写的程序,简单实用
  • VC调用matlab的数学库

    2012-08-13 11:20:38
    讲述如何在VC中调用matlab中数学库,进行各种运算
  • VC6调用matlab接口方法

    2015-05-13 11:14:37
    文档介绍了在Visual c++程序调用matlab函数的几种方法,并说明了优点与不足,方便用户使用。
  • vc调用matlab

    2012-12-25 19:57:13
    本文档详细的论述了vc调用matlab的方法,有步骤可以方面初学者
  • 教你怎样在VC6.0调用matlabf进行编程,这种方法简单实用。
  • VC调用MATLAB的方法

    2009-08-11 10:00:10
    讨论了在VC中调用MATLAB的3种方法, 并对3种方法进行了比较;通过MATLAB Engine方式可以调用C/C++函数和工具箱中的函数, 同时还可利用MATLAB中强大的图形功能, 但该种方式的致命缺陷是不可脱离MATLAB的环境.用LCC...
  • 在VS 2005使用VC7.0来调用matlab7.0进行科学计算 1、新建一个空MFC单文档项目 2、在下拉菜单工具点击选项,打开选项窗口 2、在选项窗口,选择项目-〉VC++目录,在显示目录选择包含文件,添加matlab路径 ...
  • VC6.0调用Matlab Dll的方法

    千次阅读 2013-11-16 17:42:13
    原文地址:VC调用Matlab编写的DLL作者:小木头 一. 基本环境: 1. Microsoft Visual Studio 2008 SP1(VC++);... 首先值得说明的是,经过不断的尝试和搜集资料,发现要想在VC++中调用MATLAB编写的
  • 本文是仿照这篇文章而来的:《VC调用matlab中定义的.m文件的函数的实例》他的文章使用的是VC6.0 + MATLAB6.5,有的东西已经不能使用了,因此我这里再写一篇如何用VC2005来调用MATLAB2009a编写的m文件。本例...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 334
精华内容 133
关键字:

vc中调用matlab

matlab 订阅