zoukankan      html  css  js  c++  java
  • matlab与MFC

    混合编程其实不难,关键是没有一个规范的,真正可以解决设置过程中出现的小问题的方法。我在设置的过程中,遇到了不少问题,花了多半天的时间,终于解决了,顺利地在vc中调用matlab 生成的dll文件中的函数,并返回一个值,探出对话框,显示正确。这种混合编程的方式不能脱离matlab环境,如果需要发布独立的应用程序,需要安装MCR。下面分步骤地讲一下混合编程的设置及其原因:

    1 matlab方面的操作

    首先先写一个算阶乘的函数,存成test1.m文件,该文件的内容是:

    function y = test1(n)
    y = 1 ;
    for i = 1 : n
    y = y * i ;
    end
    现在有了文件,下一步我们要设置好系统,设置好matlab,然后再把该文件编译成dll文件。

    1、在环境变量(我的电脑右键-高级)path中加入<MATLAB71_root>inwin32;

    2、添加环境变量matlab值设为< MATLAB71_root >即matlab7.1的安装路径;

    3、配置mbuild使用的C/C++编译器;

         在Matlab命令窗口中输入:

         mbuild -setup

         按照提示选择VC6.0的编译器,完成后在Matlab命令窗口中输入:

        mex -setup

        同样选择VC6.0的编译器,就完成编译器的安装和配置。

    接下来我们要把.m文件存储的程序编译成dll文件,在matlab命令窗口中输入:

    首先设置好工作目录,否则找不到文件

    mcc -W lib:test1 -T link:lib test1.m

    这个需要等一小段时间,最终,在当前目录下生成了

     

    到此,在操作系统和matlab这一方面的工作就做完了

    2 vc++6.0中的操作

    在vc中建立一个MFC AppWizard[exe]基本对话框工程,名字叫做test1app.
    1 )在 VC 中创建一个 MFC 工程(本人创建的为基于对话框的),环境设置根据如下帖子
    : 怎样设置  Visual Studio  与  Matlb Complier 4.0  一起工作   中的指导进行。在
    本例子中,只需要在 VC 中进行如下步骤: 
    A. Tools->Options->Directories->Show directories for : Include files-><matlab
    7root> ExternInclude ; 
    B. Tools->Options->Directories->Show directories for : Library files-><matlab
    7root> ExternLibWin32Microsoftmsvc60 ; 
    C. Project->Setting->C/C++->Category : Code Generation->Use run-time library 
    : Debug Multithread DLL ; 
    D. Project->Setting->Link->Category : Input->Object/library modules : test1.lib mclmcr.lib libmx.lib libmat.lib libeng.lib 

    2 )拷贝 MATLAB 当前目录下刚才用 mcc 生成的 test1.h , test1.dll , test1.lib ,以及 test1.ctf 文件到 VC 当前工程目录下,并用 Project->Add to Project->Files… 将 test1.h 加入到当前工程中。 
    3 )在当前工程的对话框的头文件和cpp中加入 #include "test1.h" 与 #include "mclmcr.h" ; 

    工程设置到此就结束了,下面开始写代码:

    首先需要在对话框的初始化程序BOOL CTest1appDlg::OnInitDialog()内写

     if( !mclInitializeApplication(NULL,0) ) //matlab环境初始化
     {
      AfxMessageBox( "Could not initialize the application.");
      exit(1);
     }

     /* Call the library intialization routine and make sure that the
        * library was initialized properly. */
     if (!test1Initialize())              //test1Initialize是test1.h中定义的test1函数的初始化函数
     {
      AfxMessageBox("Could not initialize the library.");
      exit(1);
     }

    在对话框的确定按钮的消息响应函数内,调用dll中的阶乘函数,

    void CTest1appDlg::OnOK()
    {
     // TODO: Add extra validation here

     //此处为dll中的函数准备好参数,然后调用
     double  n = 4 ;
        mxArray  * t;   //经过matlab编译完的dll 中的函数只能识别mxArray 类型的参数,所以我们在vc中定义的数值

    //都需要转换成该种格式
        t = mxCreateDoubleMatrix( 1 , 1 ,mxREAL);//该函数中的参数1,1定义了 t 这个矩阵的大小
        memcpy(mxGetPr(t), & n, sizeof ( double ));//给 t 赋值为4

     mxArray * y;      //准备一个接收返回值的变量
     y = mxCreateDoubleMatrix( 1 , 1 ,mxREAL);
       
     mlfTest1(1,&y,t);   //运行该函数,进行阶乘计算,4的
     double r1 = 0;   //vc中的接收返回值的函数
     memcpy(&r1,mxGetPr(y),sizeof(double));
        mxDestroyArray(t); //销毁废弃内存
        test1Terminate();//中止调用

     CString showrslt;
     showrslt.Format("%f",r1); 
     AfxMessageBox(showrslt);//显示阶乘计算的结果
     CDialog::OnOK();
    }

  • 相关阅读:
    Linux 性能监测:CPU
    Linux 性能监测:介绍
    数据库设计
    数据库设计
    如何将Virtualbox和VMware虚拟机相互转换
    如何将Virtualbox和VMware虚拟机相互转换
    stat()获得文件信息
    stat()获得文件信息
    网游创业为什么会失败?
    网游创业为什么会失败?
  • 原文地址:https://www.cnblogs.com/fickleness/p/3152122.html
Copyright © 2011-2022 走看看