关于Matlab的MEX技术 10分钟教会你简单的matlab和C/C++混合编程(mex文件)
2015-05-07 18:40
816 查看
10分钟教会你简单的matlab和C/C++混合编程(mex文件)
标签:matlabmexcc++
2015-05-07 18:40
379人阅读 评论(0)
收藏
举报
本文章已收录于:
分类:
Matlab(4)
作者同类文章X
版权声明:本文为博主原创文章,未经博主允许不得转载。
最近要用matlab提取视频的特征,数据量很大,程序跑起来很慢,于是把其中一个模块改为用C语言来实现。我在这里也记录一下自己的一些心得。
我用的编译器是matlab自带的Lcc-win32 C 2.4.1编译器,好处是可以不依赖高级编译器(如VS、GCC),保证程序只要有matlab即可运行;缺点是只能用C写,不能使用C++的库(比如vector、OpenCV)。所以以下这篇文章只适用于针对矩阵、数组(不包括字符串string、元胞cell)的简单的mex文件编写。
用Lcc编译器编写mex文件的几个注意事项:
1、注释不能有中文,否则报错:Specified export _mexFunction is not defined
2、所有变量定义必须在函数最前面完成,变量没有定义完,不可以执行其他操作,否则报错:illegal statement termination
下面是一个计算矩阵a-b的例子,
其中mexFunction是默认函数名,不用修改,因为matlab调用的时候用的是mex的文件名,而不是函数名。
nlhs代表的是输出参数的个数
plhs是一个指针数组,里面的指针指向mxArray类型,每一个指针指向一个输出
nrhs代表的是输入参数的个数
prhs是一个指针数组,里面的指针指向mxArray类型,每一个指针指向一个输入
[cpp]
view plain
copy
print?
#include "mex.h"
#include "matrix.h"
// b = [1 2;3 4]
// a = [5 6;7 8]
// c = mex_func(a(:), b, size(a,1)) % attention ! a is a(:)
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *data1 = mxGetPr(prhs[0]); //get pointer of a(is a vector)
double *data2 = mxGetPr(prhs[1]); //get pointer of b(is a matrix)
int data1_num = mxGetM(prhs[0]); // get elements num of data1
int data1_h = mxGetScalar(prhs[2]);//get height of matrix a
int data1_w = data1_num/data1_h; //calculate the width of matrix a
// the step above is no need when dealing with 2D matrix
int data2_h = mxGetM(prhs[1]);// get rows of data2
int data2_w = mxGetN(prhs[1]);// get cols of data2
int output_h = data1_h;
int output_w = data1_w;
int i,j;
double **copy_array;// pointer of mid-data
double *y;
//end variable defination, all the defination shoule be set at the beginning
//******************************************************
if ((data1_h!=data2_h)||(data1_w!=data2_w)){
printf("matrix dim not matched!\n");
}
//setup mid-data
copy_array = (double **)malloc(sizeof(double *) * output_h);
for(i=0; i<output_h;i++){
copy_array = (double *)malloc(sizeof(double) * output_w);
}
// calculate matrix a-b
for (i=0; i<output_h; i++){
for (j=0; j<output_w;j++){
copy_array[i][j] = data1[i+j*data1_h] - data2[i+j*data2_h];
}
}
//end calculating
//*******************************************************
plhs[0] = mxCreateDoubleMatrix(output_h,output_w, mxREAL);
y = mxGetPr(plhs[0]);
//copy the mid-data to the output pointer
for (i=0;i<output_h;i++){
for(j=0;j<output_w;j++){
*(y+i+j*output_h)=copy_array[i][j];
}
}
}
#include "mex.h" #include "matrix.h" // b = [1 2;3 4] // a = [5 6;7 8] // c = mex_func(a(:), b, size(a,1)) % attention ! a is a(:) void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *data1 = mxGetPr(prhs[0]); //get pointer of a(is a vector) double *data2 = mxGetPr(prhs[1]); //get pointer of b(is a matrix) int data1_num = mxGetM(prhs[0]); // get elements num of data1 int data1_h = mxGetScalar(prhs[2]);//get height of matrix a int data1_w = data1_num/data1_h; //calculate the width of matrix a // the step above is no need when dealing with 2D matrix int data2_h = mxGetM(prhs[1]);// get rows of data2 int data2_w = mxGetN(prhs[1]);// get cols of data2 int output_h = data1_h; int output_w = data1_w; int i,j; double **copy_array;// pointer of mid-data double *y; //end variable defination, all the defination shoule be set at the beginning //****************************************************** if ((data1_h!=data2_h)||(data1_w!=data2_w)){ printf("matrix dim not matched!\n"); } //setup mid-data copy_array = (double **)malloc(sizeof(double *) * output_h); for(i=0; i<output_h;i++){ copy_array[i] = (double *)malloc(sizeof(double) * output_w); } // calculate matrix a-b for (i=0; i<output_h; i++){ for (j=0; j<output_w;j++){ copy_array[i][j] = data1[i+j*data1_h] - data2[i+j*data2_h]; } } //end calculating //******************************************************* plhs[0] = mxCreateDoubleMatrix(output_h,output_w, mxREAL); y = mxGetPr(plhs[0]); //copy the mid-data to the output pointer for (i=0;i<output_h;i++){ for(j=0;j<output_w;j++){ *(y+i+j*output_h)=copy_array[i][j]; } } }
简单总结一下几个要点:
mex文件的编写可以分为三个步骤,数据传入,数据处理,数据导出
1、传入矩阵用mxGetPr,传入数值用mxGetScalar
2、获取2维矩阵维度用mxGetM,mxGetN,C模块无法同时获得3维矩阵的三个维度,维度需要自己手动传递
(此处有误,可以用函数mxGetDimensions: 就是返回一个指针ptr,每一个指针所指向的值是每一个维度的元素个数。例如有矩阵3*2的矩阵,那么*(ptr)为3,*(ptr+1)为2,如果是3维矩阵,只需要访问*(ptr+2)。参考文章中的第四节有详细描述)
3、数据在内存上都是连续的,访问的时候按列的顺序访问
4、数据传出用mxCreateDoubleMatrix,先创建一个double类型的指针用来存放要导出的数据,然后再拷贝到plhs[i]对应的指针上
参考文章:matlab和C/C++混合编程--Mex
顶0踩0
上一篇leetcode中Single Number II的一个通用解法
下一篇Python2.7写入中文数据进sqlite3报错
关于Matlab的MEX技术
2008-03-30 15:13:58| 分类:CAE | 标签:
|举报
|字号大中小 订阅
用微信 “扫一扫”
将文章分享到朋友圈。
用易信 “扫一扫”
将文章分享到朋友圈。
下载LOFTER
我的照片书 |
MEX文件的功能主要包括三个方面(参见文献[1]),这里主要是将Matlab作为C和Fortran代码的调试器。以下工作的软件平台为:
l
Microsoft.Visual.Studio.2005.Professional.Edition.DVD
l
Intel.Visual.Fortran.Compiler.Pro.v9.1.032
l
Matlab 7.5.0(R2007b)
以Matlab自带的timestwo.c文件为例(C:\Program Files\MATLAB\R2007b\extern\examples\refbook\timestwo.c)说明MEX的工作流程:用户在Matlab命令行(主界面中的Command
Window)下输入:
mex timestwo.c
如果编译顺利完成,同文件夹下会出现一个名为“timestwo.mexw32”的文件(Matlab版本为R2007b),再在Matlab命令行下输入:
timestwo(5.5)
输出为:
ans=
11
表示这个函数计算结果正确。要注意C文件的文件名必须是算法函数的函数名(这里二者都是timestwo)(这一条似乎不必要)。
制作C-MEX文件的具体步骤:
1.
修改原C代码。
原算法函数不需要修改,但需要新增一个名为mexFunction的函数,另外在文件头部增加“#include "mex.h"”。工作量体现在写mexFunction函数上。当用户输入“timestwo(5.5)”时,Matlab首先进入这个函数,这个函数再调用原算法函数,给出答案。因此对用户输入、输出格式是否正确的检验是在该函数中完成的。另外可以看到,原C函数格式是void
fun(y,x),但在Matlab中使用时格式是y=fun(x),这说明mexFunction函数对输入、输出格式可以自由定义。详细的写法参见文献[1]第4.3节。
2.
在Matlab中将C编译为MEX文件(如前文所述)。
3.
使用这个MEX文件(如前文所述)。另外只要这个timestwo.mexw32文件在当前目录下,关闭Matlab后重新启动仍可以直接使用timestwo函数。
如果要编译Fortran文件,先用mex
–setup将编译器改为Fortran的编译器,然后用同样的方法编译即可。
参考文献:
[1]
杨高波.精通matlab7.0混合编程.电子工业出版社,2006
评论这张
转发至微博
转发至微博
阅读(2063)|
评论(0)
|
用微信 “扫一扫”
将文章分享到朋友圈。
用易信 “扫一扫”
将文章分享到朋友圈。
MEX文件的功能主要包括三个方面(参见文献[1]),这里主要是将Matlab作为C和Fortran代码的调试器。以下工作的软件平台为:
l
Microsoft.Visual.Studio.2005.Professional.Edition.DVD
l
Intel.Visual.Fortran.Compiler.Pro.v9.1.032
l
Matlab 7.5.0(R2007b)
以Matlab自带的timestwo.c文件为例(C:\Program Files\MATLAB\R2007b\extern\examples\refbook\timestwo.c)说明MEX的工作流程:用户在Matlab命令行(主界面中的Command
Window)下输入:
mex timestwo.c
如果编译顺利完成,同文件夹下会出现一个名为“timestwo.mexw32”的文件(Matlab版本为R2007b),再在Matlab命令行下输入:
timestwo(5.5)
输出为:
ans=
11
表示这个函数计算结果正确。[i]要注意C文件的文件名必须是算法函数的函数名(这里二者都是timestwo)(这一条似乎不必要)。
制作C-MEX文件的具体步骤:
1.
修改原C代码。
原算法函数不需要修改,但需要新增一个名为mexFunction的函数,另外在文件头部增加“#include "mex.h"”。工作量体现在写mexFunction函数上。当用户输入“timestwo(5.5)”时,Matlab首先进入这个函数,这个函数再调用原算法函数,给出答案。因此对用户输入、输出格式是否正确的检验是在该函数中完成的。另外可以看到,原C函数格式是void
fun(y,x),但在Matlab中使用时格式是y=fun(x),这说明mexFunction函数对输入、输出格式可以自由定义。详细的写法参见文献[1]第4.3节。
2.
在Matlab中将C编译为MEX文件(如前文所述)。
3.
使用这个MEX文件(如前文所述)。另外只要这个timestwo.mexw32文件在当前目录下,关闭Matlab后重新启动仍可以直接使用timestwo函数。
如果要编译Fortran文件,先用mex
–setup将编译器改为Fortran的编译器,然后用同样的方法编译即可。
参考文献:
[1] 杨高波.精通matlab7.0混合编程.电子工业出版社,2006
" />
喜欢
推荐
0人 |
转载
用Matlab验证DataFit软件给出的插值函数的正确性
Fortran-MEX调试方法
相关文章推荐
- 10分钟教会你简单的matlab和C/C++混合编程(mex文件)
- 关于C++与Matlab混合编程错误??? Unexpected Standard exception from MEX file.
- 关于C++与Matlab混合编程错误??? Unexpected Standard exception from MEX file.
- 关于C++与Matlab混合编程错误??? Unexpected Standard exception from MEX file.
- 关于matlab与C++混合编程
- 关于matlab与C++混合编程,关于接口函数MexFunction的编写,特别是结构体数组的传出到matlab的方法
- Matlab & C++ 混合编程mex文件的编写与调试
- matlab和C/C++混合编程--Mex
- MEX文件调试—MATLAB调用C++程序—混合编程
- matlab和C/C++混合编程--Mex (六)参数传递
- matlab和C/C++混合编程--Mex (六)参数传递
- matlab c++混合编程入门之Mex环境配置
- matlab 生成调用c/c++ 代码 mex 简单实用
- matlab和C/C++混合编程--Mex
- MEX文件调试—MATLAB调用C++程序—混合编程
- matlab和C/C++混合编程--Mex
- 用c /c++编写mex 程序并编译MATLAB的Mex文件的方法
- matlab和C/C++混合编程--Mex (六)参数传递
- mex 混合编程 matlab调用c/c++(含lib文件)经验汇总
- matlab和C/C++混合编程--Mex