matlab和C/C++混合编程--Mex

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

一、Mex的结构

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

#include "mex.h"  

//加入头文件,该头文件在VS2010中无法include,但是不影响其在matlab中的编译,反而在matlab编译还需要include它

#include <vector>

using namespace std;

void mexFunction(int nlhs, mxArray *plhs[],int nrhs,const mxArray *prhs[]) 

//mexFunction就类似于main函数

{

    //nlhs代表的是输出参数的个数

    //plhs是一个指针数组,里面的指针指向mxArray类型,每一个指针指向一个输出

    //nrhs代表的是输入参数的个数

    //prhs是一个指针数组,里面的指针指向mxArray类型,每一个指针指向一个输入

  vector<vector<double> > 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++

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):

#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++,看下面这段代码:

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){

    double *dataCursor;

    vector<vector<double> > 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++ (传入)

char *input_buf;

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

c++ -> matlab (传出)

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)

#include "mex.h"

void revord(char *input_buf, size_t buflen, char *output_buf)

{

  mwSize i;

  if (buflen == 0) return;

  for(i=0;i<buflen-1;i++)

    *(output_buf+i) = *(input_buf+buflen-i-2);

}

void mexFunction( int nlhs, mxArray *plhs[],

                  int nrhs, const mxArray *prhs[])

{

    char *input_buf, *output_buf;

    size_t buflen;

    buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1; //因为本程序是翻转字符串,所以输入输出字符串的长度应该一样

    output_buf=mxCalloc(buflen, sizeof(char)); //申请空间

    input_buf = mxArrayToString(prhs[0]); //获得输入字符串

    revord(input_buf, buflen, output_buf); //翻转字符串

    plhs[0] = mxCreateString(output_buf); 

    mxFree(input_buf);

    return;

}

  

同样编译一下即可。


(4)cell的传入

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){

    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.http://blog.sina.com.cn/s/blog_9db9f81901013yv2.html

2.http://blog.sina.com.cn/s/blog_80202a090100uhup.html

matlab和C/C++混合编程--Mex (转载)的更多相关文章

  1. matlab和C/C++混合编程--Mex

    最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...

  2. matlab和C/C++混合编程--Mex (六)参数传递

    最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...

  3. 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...

  4. matlab和C/C++混合编程--调用opencv

    最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...

  5. matlab + c/c++ opencv 混合编程

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...

  6. MATLAB与C/C++混合编程的一些总结

    [转载请注明出处]http://www.cnblogs.com/mashiqi 先上总结: 由于C/C++语言的函数输入输出参数的特点,可以将多个参数方便地传入一个函数中,但却不能方便地返回多个参数. ...

  7. Matlab和C语言混合编程,包含目录的设定

    如果.c文件不依赖于任何第三方库,那么mex编译很简单,只需要在matlab的命令行输入 mex test.c 即可. 但是如果这个c文件使用了第三方库文件,如opencv.gsl等等,那么就需要更改 ...

  8. MATLAB和C语言混合编程-----Matlab7.0 编译器设置

    (1) mex 命令设置 (a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mex -setup ”命令后,按回车键,安装 Matlab 编译器: ...

  9. Matlab 2013a 和 VS2010 混合编程

    最近由于项目需求,某项目的算法是基于MATLAB完成的,在短时间内需要去调用算法功能.因此,基于MATLAB生成DLL, C 调用的方式完成. 环境:MATLAB 2013a + VS2010 + w ...

随机推荐

  1. RMAN备份与恢复之概念二

      1   RMAN备份恢复 1.1  基础理论 恢复可以分为完全恢复和不完全恢复 完全数据库恢复是恢复到故障发生前的状态,所有已经提交的操作都进行恢复,确保数据库不丢失任何数据,完全恢复只用于归档模 ...

  2. 【C#】:浅谈反射机制 【转】

    http://blog.csdn.net/lianjiangwei/article/details/47207875 什么是反射? 反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反 ...

  3. jquery中获取相邻元素相关的命令:next()、prev()和siblings()

    jquery里我们要获取某个元素的相邻元素时,可以用到的命令有三个: next():用来获取下一个同辈元素. prev():用来获取上一个同辈元素. siblings():用来获取所有的同辈元素. 下 ...

  4. 区域设置 ID (LCID) 表, 及获取方法

    区域设置 ID (LCID) 表, 及获取方法 中国的区域设置 ID 是 2052, 如果经常打开微软软件的安装目录应该经常见到.获取很简单, 有现成的 API 函数: GetThreadLocale ...

  5. Android adb shell学习心得(四)

    1.awk中的sub sub为替换函数.形式如 sub(/1/,"",$2) 将第二个变量的第一个1替换为空,若将sub替换为gsub.则替换全部的1. 2.awk中的-F 分隔符 ...

  6. 超酷的实时颜色数据跟踪javascript类库 - Tracking.js

    来源:GBin1.com 今天介绍这款超棒的Javascript类库是 - Tracking.js,它能够独立不依赖第三方类库帮助开发人员动态跟踪摄像头输出相关数据. 这些数据包括了颜色或者是人, 这 ...

  7. MySQL删除表的时候忽略外键约束

    删除表不是特别常用,特别是对于存在外键关联的表,删除更得小心.但是在开发过程中,发现Schema设计的有问题而且要删除现有的数据库中所有的表来重新创建也是常有的事情:另外在测试的时候,也有需要重新创建 ...

  8. 赵雅智_service生命周期

    Android中的服务和windows中的服务是类似的东西,服务一般没实用户操作界面.它执行于系统中不easy被用户发觉,能够使用它开发如监控之类的程序. 服务的开发步骤 第一步:继承Service类 ...

  9. html5:article与section元素

    article元素         aiticle元素代表文档.页面或应用程序中独立的.完整的.可以肚子被外部引用的内容.它可以使一片博客或报刊中的文章.帖子.         一个article元素 ...

  10. Java基础——线程总结

    Java基础--线程总结 一.线程是什么? 线程:一个程序里不同的运行路径. 二.怎样创建线程? 两种方法创建线程: 第一种 (1)定义详细功能类实现Runnable接口,能够多次调用而实现数据共享 ...