VC与Matlab混合编程实例(Matlab7.0函数转换成VC的.dll)

转自http://goodenoughcui.diandian.com/post/2011-05-22/40033743170

首先,是一本书叫《C语言与MATLAB接口:编程与实例》,它主要讲的是如何从Matlab中调用C语言编写的函数(c-mex函数),它介绍到Matlab是个功能完善的程序设计和数据处理的集成环境,它提供了大量的功能强大的内建函数和工具箱,几乎可以完成所有的任务。而且,matlab还提供了功能完善的API与外部程序或其它语言沟通。

虽然,我最关心的不是matlab如何去调用C语言,而是如何让C去调用Matlab。然而,本书中详细的介绍还是让我对混编有了一定的了解,例如mxArray结构体,C与matlab中矩阵的元素存取先后顺序问题(C按行,Matlab按列),C与matlab的数据交互问题,以及内存的释放问题等等。

      第二篇比较好的文章是《VC++与matlab混合编程的快速实现》,这是吉大的一个哥们写的paper,主要讲了一下如何将.m文件编译成.dll文件放入VC++程序中,这个方法实用,简单:

      1设置matlab编译环境,找到VC编译器(我用的是Matlab7.0,VS.net2003也就是msvc7.1)

      2 创建动态链接库,使用mcc命令(如,对于我下面的例子就是): mcc -W cpplib:libinverse -T link:lib inverse.m.

3在VS中使用.dll,首先要对VS做一些环境变量的配置(比较具体的配置可见http://hi.baidu.com/qmzl/blog/item/fced8a13427de427dd5401ee.html,这里有相当丰富的混合编程知识)包括对系统,VS和工程的配置,其中要在每生成一个新的工程时都要对其做工程配置(VC++6与VS2003配置小有不同,主要是有些选项的位置可能不同,可以参见前边的连接mysql时做的配置,与它的设置位置相似)。

配置完成后将前边生成的.ctf .dll .h.lib(对下面的例子就是libinverse.ctf,libinverse.dll, libinverse.hlibinverse.lib)文件放入VC程序主目录下面,把libinverse.h添加到程序中,这样就可以使用刚才的libinverse.dll了(只要在使用它的文件中加入#include“libinverse.h”)。

给出一个具体的实例:

我在matlab中写一个简单的inverse.m实现求矩阵的逆:

functiony=inverse(a,NUM)

%NUM是a的维数,这里没有什么实际意义

y=inv(a);

 

VC调用 :

 

//Test_matlab.cpp : Defines the entry point for the consoleapplication.

//程序中包括我做的一些其它的测试,例如内存的写顺序,如何传递参数等等问题

#include"stdafx.h"

#include"mclmcr.h" // mxArray 类型声明

#include"libinverse.h" // DLL 头文件

intmain()

{

//初始化程序

      int i,j;

      if( ! mclInitializeApplication(NULL,0) )

      {

             fprintf(stderr, "Could not initialize theapplication.\n");

             exit(1);

      }

//初始化库

      if (! libinverseInitialize() )

      {

             fprintf(stderr,"Could not initialize the library.\n");

             exit(1);

      }

      printf("game over!\n");

      int NUM=2600;

      double **xx=new double*[NUM];

      xx[0]=new double[NUM*NUM];

      for(i=0;i<NUM;i++)

      {

             xx[i]=xx[0]+i*NUM;

      }

      double *x=new double[NUM*NUM];

      for(i=0;i<NUM;i++)

             for(j=0;j<NUM;j++)

             {

                    if(i==j)

                           xx[i][j]=2;

                    else

                           xx[i][j]=0;

             }

      for( i=0;i<NUM;i++)

             for( j=0;j<NUM;j++)

             {

                    x[i*NUM+j]=xx[j][i];                //matlab一列一列地写

             }

      mxArray*n;                                                                           //输入变量

      mxArray* a;

      mxArray*y=NULL;                                                                    //输出变量

      n=mxCreateScalarDouble(NUM);                                    //创建一个标量

      a=mxCreateDoubleMatrix(NUM,NUM,mxREAL);                  //分配内存

      memcpy(mxGetPr(n),&NUM,sizeof(int));                     //注意这里是指针型&NUM,给mxArray对象赋值

      memcpy(mxGetPr(a),x,NUM*NUM*sizeof(double));              //vc与matlab间进行数据交互,把int转换成mxArray类型

      printf("beginning\n");

      mlfInverse(1,&y,a,n);            //在头文件中此函数的声明是: extern voidmlfInverse(int nargout, mxArray** y, mxArray* a, mxArray*NUM);,其中nargout是输出参数个数,**y是输出参数,后面两个是输入参数

      printf("ending!\n");

      mxDestroyArray(a);

      

      double *data;

      double **mm=new double*[NUM];

      mm[0]=new double[NUM*NUM];

      for(i=0;i<NUM;i++)

      {

             mm[i]=mm[0]+i*NUM;

      }

      data=mxGetPr(y);

      int r,c;

      r=mxGetM(y);                    //行数=NUM

      c=mxGetN(y);                                  //列数=NUM

      for(i=0;i<r;i++)

 

      {

             for(j=0;j<c;j++)

             {

                    mm[i][j]=data[j*r+i];          //注意这里的行列倒置

                    //printf("% 4.2f ",mm[i][j]);

             }

             //printf("\n");

      }

      

      //mxFree(y);                                                   //mxFree这里不能用mxDestroyArray(y),因为它只能用来释放mxArray阵列所占的内存

      mxFree(n);

      //mxDestroyArray(n);

      mxDestroyArray(y);       //y虽然不是我们创建的,但它在函数调用过程中会分配内存(因为它是一个矩阵),所以一定要释放否则会有内存泄漏

      libinverseTerminate();                               //关闭库和程序

      mclTerminateApplication();

      delete[] x;

      delete[] mm[0];

      delete[] mm;

      delete[] xx[0];

      delete[] xx;

}

由此可见,VC调用Matlab不仅可以提高程序的运行速度,而且有一个更重要的意义是以后我们编程时就可以用这种方法直接调用Matlab中的数值运算函数,而不必自己手动编写了,不用担心自己程序的准确与速度问题了。

但后边的问题是程序如何在没有matlab的环境中进行,这点我还没有仔细去实验,而且还有个问题matlab7.0是不支持VS2005(msvc8)的,具体如何使二者结合起来也的确是个问题,但是可以选择使用matlabR2007b和VS2005进行组合,而且R2007b好象是有多线程运算功能,现在多核如此流行,如果能用多线程计算,也算是充分地利用了硬件,提高了运算效能。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值