matlab和c++混合编程 您所在的位置:网站首页 数组传入函数的实例 matlab和c++混合编程

matlab和c++混合编程

2024-06-30 14:50| 来源: 网络整理| 查看: 265

最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题。现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加。首先讲讲写Mex的一些常规规定,然后我们会重点关注混合编程中最难解决数据的问题--结构到底如何转换,并且后面会重点说一下自己的程序。

 

一、Mex的结构

先看一个简单的程序(该程序保存在matlab主目录下名字是mexDemon.cpp,或者在主目录下新建一个.cpp文件):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include "mex.h"  //项目---右键属性---c/c++---常规---附加包含目录---添加“D:\programs installing\matlab2016\extern\include”,将mex.h包含进去。 //加入头文件,该头文件在VS2010中无法include,但是不影响其在matlab中的编译,反而在matlab编译还需要include它 #include using  namespace  std; void  mexFunction( int  nlhs, mxArray *plhs[], int  nrhs, const  mxArray *prhs[]) //mexFunction就类似于main函数 {      //nlhs代表的是输出参数的个数      //plhs是一个指针数组,里面的指针指向mxArray类型,每一个指针指向一个输出      //nrhs代表的是输入参数的个数      //prhs是一个指针数组,里面的指针指向mxArray类型,每一个指针指向一个输入   vector array2d;      double  *z;      plhs[0] = mxCreateDoubleMatrix( 5, 6, mxREAL); //第一个输出是一个5*6的矩阵      z = mxGetPr(plhs[0]); //获得矩阵的第一个元素的指针      array2d.resize(5);      int  ii = 0;      for ( int  i = 0; i < 5; i++){          for ( int  j = 0; j < 6; j++){              z[i*6 + j] = ii;  //指针访问矩阵是列优先的,请自己循环程序和分析输出结果              ii++;          }      } }  /*   *ans =       0     5    10    15    20    25       1     6    11    16    21    26       2     7    12    17    22    27       3     8    13    18    23    28       4     9    14    19    24    29   */

然后对Matlab编译应用程序mex的编译器进行设置,在命令窗口输入 Mex –setup。 然后跟着步骤走选择合适的编译器即可。

设置完编译器之后在命令窗口输入Mex mexDemon.cpp 进行编译生成.mexw64文件,生成之后便可以直接调用了,例如本例子可以这样调用,就是直接在命令窗口输入 a = mexDemon(); 返回值如上。

 二、C和Matlab的数据结构的转换

(1)数值的传递

matlab -> c++

1 x = mxGetScalar(prhs[0]); //该函数获取matlab传递过来的数值;

 c++ -> matlab

plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);//创建返回的矩阵,范围plhs[0]为mxArray类型 y = mxGetPr(plhs[0]);//获取返回plhs[0]的数据地址,其后可以修改y的值就可以返回了

一个实例(numDemon.cpp):

1 2 3 4 5 6 7 8 9 10 11 #include "mex.h" void  mexFunction( int  nlhs, mxArray *plhs[],  int  nrhs,  const  mxArray *prhs[]){      int  x = mxGetScalar(prhs[0]);  //将第一个输入参数转为Scalar标量,也就是单数值      printf ( "%d\n" , x);  //打印            double  *y;      plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);  //让第一个输出参数指向一个1*1的矩阵      y = mxGetPr(plhs[0]);  //获得矩阵的第一个元素的指针      *y = 10;  //将其赋值为10 }

 如下图在命令窗口编译:

 (2)矩阵的传入与传出

关于传出(c++到Matlab, 就是第一个例子),下面可以再给一个例子是如何从matlab传入到c++,看下面这段代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include "mex.h" void  mexFunction( int  nlhs, mxArray *plhs[],  int  nrhs,  const  mxArray *prhs[]){      double  *dataCursor;      vector parms;      dataCursor = mxGetPr(prhs[0]);  //得到输入矩阵的第一个元素的指针      int  mrows = mxGetM(prhs[0]);    //获得矩阵的行      int  ncols = mxGetN(prhs[0]);    //获得矩阵的列      printf ( "%d_%d\n" , mrows, ncols);   //打印行和列            parms.resize(mrows);   //初始化      for ( int  i = 0; i < mrows; i++){          parms[i].resize(ncols);      }      for ( int  i = 0; i < mrows; i++){          for ( int  j = 0; j < ncols; j++){              parms[i][j] = dataCursor[j * mrows + i];  //拷贝矩阵的元素到vector of vector          }      } }

 同样在命令窗口编译即可。

(3)字符串的传入与传出

matlab -> c++ (传入)

1 2 char  *input_buf; input_buf = mxArrayToString(prhs[0]); //使用mxArrayToString将mxArray转换为c、c++字符串

 c++ -> matlab (传出)

1 2 3 4 5 char  *output_buf; //定义字符串缓存 size_t  buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1; //获取字符串长度,mxGetM获取行数,mxGetN获取列数 output_buf=mxCalloc(buflen,  sizeof ( char )); //使用mxCalloc分配输出字符串数组 plhs[0] = mxCreateString(output_buf); //使用mxCreateString创建mxArray输出 mxfree(output_buf);

 一个实例(strDemon.cpp)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include "mex.h" void  revord( char  *input_buf,  size_t  buflen,  char  *output_buf) {    mwSize i;    if  (buflen == 0)  return ;       for (i=0;i      mwSize cellNdim = mxGetNumberOfDimensions(prhs[0]);  //这里介绍两个函数mxGetNumberOfDimensions和mxGetDimensions      const  int  *cellColPtr = mxGetDimensions(prhs[0]);      //mxGetDimensions: 就是返回一个指针ptr,每一个指针所指向的值是每一个维度的元素个数。例如有矩阵3*2的矩阵,那么*(ptr)为3,*(ptr+1)为2.      //mxGetNumberOfDimensions: 返回mxArray的维度。      int  cellNRow = *(label_dims);      int  cellNCol = *(label_dims + 1);      mxArray *ptr;      ptr = mxGetCell(prhs[0], 0);  //获取cell的第0个元素,返回一个mxArray指针,第二个参数代表cell中元素的下标      mxArray *cellOfCell;      cellOfCell = mxGetCell(ptr, 0);     //当然cell里面可以还是cell,那么应该再样写      mxArray *cellOfStr;      char  *chTmp;      cellOfStr = mxGetCell(prhs[0], 0);  //当然cell里面可以是字符串      chTmp = mxArrayToString(cellOfStr);      printf ( "%s\n" , chTmp); }

 后面待补充结构体和cell数组的传出,暂时还没遇到这样的需求。再贴上几个参考网址:

1.Matlab 与 c c++混合编程(二)_sunanger_新浪博客

2.matlab与C的混合编程之入门_陌路人_新浪博客



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有