matlab和C/C++混合编程--Mex (六)参数传递
最近的项目需要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" //加入头文件,该头文件在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++
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++,看下面这段代码:
如:matlab传进来的矩阵为与指针访问的顺序对应
0 3 6 9
1 4 7 10
2 5 6 11
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<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++ (传入)
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<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的传入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#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
感谢http://www.cnblogs.com/Key-Ky/p/4233581.html
matlab和C/C++混合编程--Mex (六)参数传递的更多相关文章
- matlab和C/C++混合编程--Mex (转载)
matlab和C/C++混合编程--Mex 最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续 ...
- matlab和C/C++混合编程--Mex
最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...
- 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...
- matlab和C/C++混合编程--调用opencv
最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...
- matlab + c/c++ opencv 混合编程
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...
- MATLAB与C/C++混合编程的一些总结
[转载请注明出处]http://www.cnblogs.com/mashiqi 先上总结: 由于C/C++语言的函数输入输出参数的特点,可以将多个参数方便地传入一个函数中,但却不能方便地返回多个参数. ...
- Matlab和C语言混合编程,包含目录的设定
如果.c文件不依赖于任何第三方库,那么mex编译很简单,只需要在matlab的命令行输入 mex test.c 即可. 但是如果这个c文件使用了第三方库文件,如opencv.gsl等等,那么就需要更改 ...
- MATLAB和C语言混合编程-----Matlab7.0 编译器设置
(1) mex 命令设置 (a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mex -setup ”命令后,按回车键,安装 Matlab 编译器: ...
- Matlab 2013a 和 VS2010 混合编程
最近由于项目需求,某项目的算法是基于MATLAB完成的,在短时间内需要去调用算法功能.因此,基于MATLAB生成DLL, C 调用的方式完成. 环境:MATLAB 2013a + VS2010 + w ...
随机推荐
- mybatis <sql /> 配置中 返回值 resultType 与resultMap的区别
mybatis的objectMapper.xml中, 1) 若<sql /> 查询语句中配置的是resultType=“实体类/DTO” ,则从mybatis返回的键值对结果集(Map)会 ...
- fedora 关闭、禁止selinux
Fedora关闭/禁用SELinux三种方法 在Fedora中有时候我们想关闭SELinux,因为有时候本是合法的操作也总是弹出窗口阻止我们的操作.下面介绍三种方法来关闭/禁用SELinux. 1.在 ...
- 在Linux或者Unix下打开,每一行都会出多出^M这样的字符
Windows上写好的文件,在Linux或者Unix下打开,每一行都会出多出^M这样的字符,这是因为Windows与*nix的换行符不同所致,我们看看文件格式有什么不同. 在Linux下查看文件格式: ...
- 为什么删不掉date模块
显示是field pending deletion一看report里面的field list并没有xxx_date_xxx,只好跑到数据库才看到一个field_date_test当时并没有把这个字段当 ...
- perl中->和=>作用
-> 用法 -> 有两种用法,都和解引用有关. 第一种用法,就是解引用. 根据 -> 后面跟的符号的不同,解不同类型的引用, ->[] 表示解数组引用,->{} 表示解散 ...
- sap 中怎样把非限制库存转为销售订单库存?
把非限制库存转为销售订单库存: MB1B 移动类型413 把销售订单库存转为非限制库存: MB1B移动类型411 E 切记!
- fushioncharts的使用教程
FusionCharts 是使用javascript 实现统计图表的js组件:其官网地址:http://www.fusioncharts.com.其早期版本FusionCharts Free 是基于f ...
- parent,parents和closest
1.parent parent() 获得当前匹配元素集合中每个元素的父元素,使用选择器进行筛选是可选的. <ul id="menu" style="width:10 ...
- 《Java程序设计》第九周学习总结
20145224 <Java程序设计>第九周学习总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的 ...
- java多线程的常用方法(以及注意事项)
/* * 线程的常用方法 * 1.start(); * 2.run(); * 3.sleep(int millsecond); * 4.isAlive(); -->判断线程是否还在运行 * 5. ...