• VC++与Matlab混合编程2


    在VC中调用MATLAB的,总结有以下几种方法:1、是调用Matlab引擎;2、是调用Matlab中M函数转化成的dll文件;3、调用Matlab中M函数转化成c语言的函数。

      第一种方法

     一、设置VC相关属性。

        (1)Visual C++6.0 编译环境的设置:通过菜单 Tools/ Options,打开Visual C++6.0设置属性页,进入 Directorie页面,在 Show Directories for下拉列表中选择Include Files,添加路径:<matlab>\extern\include(在Matlab的安装路径下);再选择下拉列表中的 Library Files,添加路径:<matlab>\extern\ lib\win32\Microsoft(在Matlab的安装路径下,但是在我查看资料的时候看到很多是<matlab>\extern\ lib\win32\Microsoft\msvc60这个路径,但是我用的是MatlabR2009a,或许这里设置有点区别)。看资料说编译环境或许只需设置一次,但是我在设置的时候每次都要设置。

        (2)添加库文件: 通过菜单 Projects|settings,进入 Link 页面,在 Object/Library Modules 框中,添加库文件名:libmx.lib 、libmat.lib 、libeng.lib。每个新的工程文件都要单独添加库文件。

     二、在VC中通过MATLAB引擎调用Matlab函数命令:

              现在以画一个正弦曲线的图为例。

             1、 新建一个MFC程序,命名Test,基于对话框。

              
            2、在Testdlg.cpp中加入头文件:

    #include "engine.h"
    #include <stdlib.h>

            3、添加botton  Test,并添加点击命令,加入代码如下:

    void CTestDlg::OnTest()
    {
     // TODO: Add your control notification handler code here
     Engine *ep;
     
     if (!(ep = engOpen(NULL))) //打开Matlab引擎

     {              

         MessageBox ("Can't start MATLAB engine", MB_OK);

         exit(-1);

     } 

     engSetVisible(ep, 0);
     
     engEvalString(ep,"x=0:0.001:2*pi;");
     
     engEvalString(ep,"y=sin(x);");     
     
     engEvalString(ep,"plot(x,y)");//会显示出图
    }

            4、运行程序,单击Test按钮,运行结果如下图:

            

    至此,利用VC调用Matlab引擎结束,可以运行Matlab中的各种函数,作图等。此种方法的特点是,非常简单和方便,要求运行程序的电脑必须装有Matlab软件,因此也具有不能脱离Matlab环境的弱点。

    备注:此次测试是基于Visual C++6.0和Matlab R2009a的环境。

    上面例子是VC和Matlab的混合编程的一个简单应用,在实际的数值计算,控制系统开发等工程应用中,可以很好的利用VC和Matlab的混合编程技术,从而简化应用程序的开发工作量。

     

     

     

    第二种方法:利用Matlab生成DLL文件,然后用VC调用DLL文件,此种方法是将Matlab写的函数封装在动态链接库里面,然后用VC调用动态链接库,优点是程序的运行可以脱离Matlab的环境独立运行。

    在VC中调用MATLAB的,总结有以下几种方法:1、是调用Matlab引擎;2、是调用Matlab中M函数转化成的dll文件;3、调用Matlab中M函数转化成c语言的函数。在本文当中重点讲解第二种方法,调用Matlab中M函数转换成DLL文件的形式。
    在我自己编写之前,查看了很多的文献,但是每个文献所应用的Matlab的版本不一样,很多数学函数对应的库不一样,导致最终的函数出错,本次练习和测试也是出现在了一个lib文件没有找到问题,查找了很长时间,一个一个的对出来才找到的错的原因。
    因此在开始我们编程之前想告诉大家的是,我们在中间过程当中可能会遇到很多的问题,但是这个时候一定要坚持下去,多查文献,同时积极向高手请教,只有这样才能做出成品,不然的话我们只能中途而废。好了,现在开始正文。
    在VC6.0下调用Matlab的M文件,基本可以分为一下几个大步骤,1、对Matlab的编译环境进行配置;2、编写M函数生成DLL文件;3、编写VC程序,对工程进行配置;4、调用生成的DLL文件中的函数;5、程序的调试和发布。
    一、Matlab编译环境的设置
    为了在开发时实现对MATLAB的具体功能的调用,应首先在操作系统中安装MATLAB工具软件,之后并运行此工具软件,依次执行
    mex –setup
    mbuild –setup
    此时一定要注意横线前面的空格,最好不要复制,自己手工输入到Matlab的命令对话框当中,不然会出现错误,很多人在这里遇到了问题。
    >> mex -setup
    Please choose your compiler for building external interface (MEX) files: 
     
    Would you like mex to locate installed compilers [y]/n? 
     
    Select a compiler: 
    [1] Lcc-win32 C 2.4.1 in D:\PROGRA~1\MATLAB\R2009a\sys\lcc 
    [2] Microsoft Visual C++ 6.0 in D:\Program Files\Microsoft Visual Studio 
     
    [0] None 
     
    Compiler: 2
     
    Please verify your choices: 
     
    Compiler: Microsoft Visual C++ 6.0 
    Location: D:\Program Files\Microsoft Visual Studio 
     
    Are these correct [y]/n? 
     
    Trying to update options file: C:\Users\Robin\AppData\Roaming\MathWorks\MATLAB\R2009a\mexopts.bat 
    From template:              D:\PROGRA~1\MATLAB\R2009a\bin\win32\mexopts\msvc60opts.bat 
     
    Done . . . 
     
    ************************************************************************** 
      Warning: The MATLAB C and Fortran API has changed to support MATLAB 
               variables with more than 2^32-1 elements.  In the near future 
               you will be required to update your code to utilize the new 
               API. You can find more information about this at: 
               http://www.mathworks.com/support/solutions/data/1-5C27B9.html?solution=1-5C27B9
               Building with the -largeArrayDims option enables the new API. 
    ************************************************************************** 
     
    >>
    以上是运行mex –setup的情况。
    >> mbuild -setup
    Please choose your compiler for building standalone MATLAB applications: 
     
    Would you like mbuild to locate installed compilers [y]/n? 
     
    Select a compiler: 
    [1] Lcc-win32 C 2.4.1 in D:\PROGRA~1\MATLAB\R2009a\sys\lcc 
    [2] Microsoft Visual C++ 6.0 in D:\Program Files\Microsoft Visual Studio 
     
    [0] None 
     
    Compiler: 2
     
    Please verify your choices: 
     
    Compiler: Microsoft Visual C++ 6.0 
    Location: D:\Program Files\Microsoft Visual Studio 
     
    Are these correct [y]/n? 
     
    Trying to update options file: C:\Users\Robin\AppData\Roaming\MathWorks\MATLAB\R2009a\compopts.bat 
    From template:              D:\PROGRA~1\MATLAB\R2009a\bin\win32\mbuildopts\msvc60compp.bat 
     
    Done . . . 
     
    >>
    以上为运行mbuild –setup的情况。
    二、写M函数,创建动态链接库(*.DLL)
    1、创建动态链接库主要有两种方法:
    一种是使用 Matlab为VC++ IDE提供的Add-in。这种方法比较简单,方便快捷,只要 在VC++中创建工程的时候选择Matlab Project Wizard,并且在接下来的Step1中的Visual Matlab Application Type 选择 Shared M-DLL就可以了。接下来就是添加*.m文件, 进行编 译 了。
    另一种方法就是使用Matlab的mcc命令将*.m文件编译为动态链接库(*.DLL)。
    mcc–B csglsharedlib: youlibname function1 funcion2…来创建我们所需要的动态链接库 DLL文件。其中参数-B表示使用的是Bundle Files作为参数,csglsharedlib是-B的参数,意 思是生成使用Matlab图形库的C共享动态链接库,youlibname是你想要生成的动态链接库 DLL的文件名,注意csglsharedlib与youlibname之间有一个冒号“:”连接,function1为你想要加入到动态链接库DLL中的函数名,如果有多个函数,各个函数名用空格隔开。
    举例:创建所需的Matlab函数文件 MyAdd.m
    function [c] = MyAdd(a, b);  
    c = a + b; 
    然后,进行编译,命令如下:
    mcc -W cpplib:libMyAdd -T link:lib MyAdd
    其中,mcc是Matlab提供的编译命令,对于这一点,Matlab的帮助说明如下:
    -W lib:string link:lib其中-W是控制编译之后的封装格式,cpplib,是指编译成C++的lib,cpplib冒号后面是指编译的库的名字,-T表示目标,link:lib表示要连接到一个库文件的目标,目标的名字是后面的MyAdd,即你写的m函数的名字。
    运行完之后,你的目录下面,将会出现以下一些文件:
    libMyAdd.cpp
    libMyAdd.exp
    libMyAdd.dll
    libMyAdd.exports
    libMyAdd.h
    libMyAdd.prj
    libMyAdd_mcc_component_data.c
    mccExcludedFiles.log
    readme.txt
    具体每一个文件的意思,请查帮助,这里只说其中很有用的几个:
    libMyAdd.dll是编译好的动态库,MyAdd这个函数封装在里面,libMyAdd.h是对应的头文件,在C里面调用这个函数的时候,需要include这个头文件,在这个头文件的最后,你可以看到下面的内容:
    extern LIB_libMyAdd_CPP_API void MW_CALL_CONV MyAdd(int nargout, mwArray& c, const mwArray& a, const mwArray& b);
    这就是MyAdd的C函数的声明。nargout表示输出变量的个数,a,b,c就是对应了m函数的几个变量。
    注意,a,b,c三个变量的类型是mwArray,这是Matlab提供的一个特殊的变量类型(在7.0的版本,编译之后,变量类型是mxArray)。mwArray是一个类,具体可以查帮助,当然后面也会讲到。
    三、在VC++中使用Matlab生成的动态链接库(*.DLL)
    首先新建一个基于MFC的对话框程序,太简单了,取名为Add,然后进行如下设置:
     
    1、设置 Include 和 Library 目录
    在VC++IDE中选择Tools->Options->Directories。
    在 Show directoris for:中选择Include files,添加如下两个目录:
     

    在 Show directoris for:中选择Library files,添加如下两个目录:
     
    这里假设<Matlab>为你的Matlab的安装目录。这些操作只需要一次。以后的工程中不需再进行操作。
    2、工程 (project)本身的一些设置 
    在 VC++ IDE中选择 Project->Setting->Link
    在Category中选择General,在Object/library modules中添加mclmcrrt.lib libmx.lib libmat.lib mclmcr.lib libMyAdd.lib
     
    3、为工程添加相应的文件
    把刚才生成的libMyAdd.h libMyAdd.dll libMyAdd.lib文件复制到VC++工程的文件夹下,并且用add to project//files… 添加的工程中(如果遇到添加文件到工程的命令没有反应的时候可以尝试将Office卸载掉,我在编程的时候就遇到了这个问题)。
     4、使用DLL
    (1)首先要在使用DLL中函数的源文件中加上头文件libMyAdd.h。如下再加上另外两个数学函数的头文件:
    #include "mclmcr.h"   
    #include "matrix.h"
    #include "libMyAdd.h"
    (2)注册DLL
    在使用之前还需要对libMyAdd.dll进注册,使用完毕之后需要对其进行释放。注册使用函数libMyAddInitiallize();释放使用函数libMyAddTerminate()。
    函数名的规则就是youlibname+Initialize(Terminate)。 这两函数在libMyAdd.h 中可以找到。
    libMyAddInitialize()不仅注册了刚才生成的libMyAdd.dll,同时它也注册了Matlab本身的一些动态链接库(*.DLL);同理libMyAddTerminate()不仅释放了刚才生成的libMyAdd.dll,同时它也释放了Matlab本身的一些动态链接库(*.DLL)。因此在注册了libMyAdd.dll之后,我们也可以使用 Matlab的数学库中的函数,例如mlfabs(),mlfAssign()等等 。 
    在使用libMyAdd.dll 的时候,存在着一个VC++和libMyAdd.dll中的函数之间数据交互的问题 。
    由于libMyAdd.dll中的函数所接受的参数是mxArray 型数据 。因此我们要使用Matlab为 我们提供的External Interfaces/ API 函数来创建mxArray 型数据,大量的API函数可参见Matlab 的帮助文件Matlab\External Interfaces/API Reference\C MX-Functionsx 小节。还有一个需要注意的问题就是原来的函数名myfun 变成了mlfMyfun。可以在libMyAdd.h中看到。
    下 面 就是一个 实 例 
    void CAddDlg::OnAdd() 
    {
     // TODO: Add your control notification handler code here
     double a = 6;   
     double b = 8;   
     double c; 
     if(!libMyAddInitialize())   
     {   
      MessageBox("Could not initialize libMyAdd!");   
      exit(-1); 
     }  
     mwArray mwA(1, 1, mxDOUBLE_CLASS);
     mwArray mwB(1, 1, mxDOUBLE_CLASS);  
     mwArray mwC(1, 1, mxDOUBLE_CLASS);   
     mwA.SetData(&a, 1);   
     mwB.SetData(&b, 1);
     MyAdd(1, mwC, mwA, mwB);  
     c = mwC.Get(1, 1);   
     CString str;
     str.Format("%.0f",c);
     MessageBox(str,"求和结果");
     libMyAddTerminate();  
    }
    四、对程序进行运行和调试
     调试结果如下图:

  • 相关阅读:
    How To Scan QRCode For UWP (4)
    How To Crop Bitmap For UWP
    How To Scan QRCode For UWP (3)
    How To Scan QRCode For UWP (2)
    How To Scan QRCode For UWP (1)
    How to change windows applicatioin's position via Win32 API
    8 Ways to Become a Better Coder
    How to resize or create a thumbnail image from file stream on UWP
    C# winform压缩文件夹带进度条
    MS ACCESS MID函数
  • 原文地址:https://www.cnblogs.com/nktblog/p/2435624.html
Copyright © 2020-2023  润新知