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

一、Mex的结构

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

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

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

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


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

(1)数值的传递

matlab -> c++

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

c++ -> matlab

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

一个实例(numDemon.cpp):

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

如下图在命令窗口编译:


(2)矩阵的传入与传出

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

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

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


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

matlab -> c++ (传入)

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

c++ -> matlab (传出)

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

一个实例(strDemon.cpp)

  1. #include "mex.h"
  2. void revord(char *input_buf, size_t buflen, char *output_buf)
  3. {
  4. mwSize i;
  5. if (buflen == 0) return;
  6.  
  7. for(i=0;i<buflen-1;i++)
  8. *(output_buf+i) = *(input_buf+buflen-i-2);
  9. }
  10.  
  11. void mexFunction( int nlhs, mxArray *plhs[],
  12. int nrhs, const mxArray *prhs[])
  13. {
  14. char *input_buf, *output_buf;
  15. size_t buflen;
  16.  
  17. buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1; //因为本程序是翻转字符串,所以输入输出字符串的长度应该一样
  18.  
  19. output_buf=mxCalloc(buflen, sizeof(char)); //申请空间
  20.  
  21. input_buf = mxArrayToString(prhs[0]); //获得输入字符串
  22.  
  23. revord(input_buf, buflen, output_buf); //翻转字符串
  24.  
  25. plhs[0] = mxCreateString(output_buf);
  26. mxFree(input_buf);
  27. return;
  28. }

同样编译一下即可。


(4)cell的传入

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

后面待补充结构体和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/C++混合编程--Mex 最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将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. 为什么要加入<!doctype html>这个文档声明——IE怪异模式

    调试了很久,发现了一个非常细微但又十分重要的问题,又一次我在对于文档声明类型的时候,声明了如下类型 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...

  2. alarm

    AlarmManager的使用机制有的称呼为全局定时器,有的称呼为闹钟.通过对它的使用,它的作用和Timer有点相似.都有两种相似的用法:(1)在指定时长后执行某项操作 (2)周期性的执行某项操作 在 ...

  3. 39-tar 打包压缩

    将文件存储到归档文件中或者从归档文件中获取原始文件,以及为文件创建归档文件 tar [option] [modifiers] [file-list] 参数 file-list是tar进行归档和提取的文 ...

  4. RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)

    路由(Routing) 在前面的教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重的错误日 ...

  5. 简单的解释XSS攻击

    XSS 跨站点脚本 cross site script 怎么造成攻击? 举例:有一个公共的页面,所有用户都可以访问且可以保存内容,输入的时候若输入<script>alert('I am h ...

  6. Java开发利器Myeclipse全面详解

    Java开发利器Myeclipse全面详解: Ctrl+1:修改代码错误 Alt+Shift+S:Source命令 Ctrl+7:单行注释 Ctrl+Shift+/ :多行注释 Ctrl+I :缩进( ...

  7. Java--笔记(1)

    1.Swing 是在AWT的基础上构建的一套新的图形界面系统,它提供了AWT 所能够提供的所有功能,并且用纯粹的Java代码对AWT 的功能进行了大幅度的扩充.AWT 是基于本地方法的C/C++程序, ...

  8. Java创始人

    詹姆斯·高斯林(英语:James Gosling,1955年5月19日-),出生于加拿大,软件专家,Java编程语言的共同创始人之一,一般公认他为“Java之父”. 在他12岁的时候,他已能设计电子游 ...

  9. thinkphp全站静态页实现方法

    1:在根目录下的全局index.php中加下面这行: define('HTML_PATH', './htm');//生成静态页面的文件位置 2:在项目的配置文件config.php中加下面这行: 'H ...

  10. Maven插件maven-surefire-plugin

    插件官方文档:maven-surefire-plugin 1.surefire plugin的作用surefire 插件用来在maven构建生命周期的test phase执行一个应用的单元测试. 它会 ...