1、为什么我们要用C_MEX 文件
我们知道Matlab擅长处理矩阵运算,提供了很多内建函数以及工具箱,但是对于大量循环的处理效率较低,会出现计算速度的瓶颈,而C对于循环有着高效的处理方式。结合两者特性,我们尝试将耗时的部分改用C实现,由Matalb进行调用。通过使用mex文件,使得Matlab调用C程序与调用内置函数一样简单。
2.、mex文件的组成
C语言MEX 函数主要由计算子程序和接口子程序两个部分组成。
>C和Matlab之间的接口函数(由mexFunction实现)
>用C编写的实现特定功能的计算程序(由用户编写完成特定的功能)
>与平台相关的预处理宏(Windows平台下与C相关的宏,主要与mxArray类相关)
注: 将C/Cpp 文件编译为matlab可以执行的程序,关键是“数据格式的转换”。Matlab中使用的是矩阵类型,一个标量也是使用矩阵进行表述的;而C/CPP中使用的初级类型是int,double等。如何将两类数据调整一致是一个基本问题。
mex文件入口函数:void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[]);
mexFunction四个参数的意思为:
nlhs= 1,说明调用语句左手面(lhs-lefthand side)有一个变量,即a。
nrhs= 2,说明调用语句右手面(rhs-righthand side)有两个自变量,即b和c。
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
注:因为Matlab最基本的单元为array,无论是什么类型也好,如有double array、 cell array、 struct array……所以a,b,c都是array,b= 1.1便是一个1x1的doublearray。而在C语言中,Matlab的array使用mxArray类型来表示。所以就不难明白为什么plhs和prhs都是指向mxArray类型的指针数组。
1
2
3
4
5
6
7function [ z ] = mexAdd( x,y ) %UNTITLED Summary of this function goes here % Detailed explanation goes here disp('this is a function.'); z = x+y; end
现在,我们要用C的方式来实现:
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//包含头文件 #include "mex.h" //C 函数 double mexAdd(double x,double y){ return x+y; } //MEX文件的入口函数mexFunction void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[]){ double a; double b; double *c; //输入参数、输出参数判断 if(nlhs != 1){ mexErrMsgTxt("One output required!"); } if(nrhs != 2){ mexErrMsgTxt("Two input required!"); } //传入的mxArray参数,利用Matlab提供的API函数转成C/C++数据 a = *( mxGetPr(prhs[0]) ); b = *( mxGetPr(prhs[1]) ); plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); c = mxGetPr(plhs[0]); *c = mexAdd(a,b); }

然后就是使用mex命令编译C文件了,编译成功后生成对应的 .mexw64文件或者.mexw32文件,调用时跟普通内建函数使用无区别。
4、数组相加实例
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
37
38
39
40
41
42
43# include "mex.h" void mexArrayAdd(const int Row,const int Col,const double *A,const double *B,double *C){ int i,j; for(i=0;i<Row;i++){ for(j=0;j<Col;j++){ //注意数据的表达方式, C语言是按行存储A[i*Col+j],matlab是按列存储 A[i+j*Row] C[i+j*Row] = A[i+j*Row] + B[i+j*Row]; } } } void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]){ double *A,*B,*C; int RowA,ColA,RowB,ColB; if(nlhs != 1){ mexErrMsgTxt("One output required."); } else if(nrhs > 2){ mexErrMsgTxt("Two input required."); } if( !mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1]) || mxIsComplex(prhs[0]) || mxIsComplex(prhs[1]) ){ mexErrMsgTxt("Input Array must be double."); } //获得矩阵的行数 RowA = mxGetM(prhs[0]); //获得矩阵的列数 ColA = mxGetN(prhs[0]); RowB = mxGetM(prhs[1]); ColB= mxGetN(prhs[1]); //判断行列是否相等 if(RowA != RowB || ColA != ColB){ mexErrMsgTxt("Rows and Cols must be same."); } //获取指向输入参数的指针 A = mxGetPr(prhs[0]); B = mxGetPr(prhs[1]); //生成输出参量的mxArray plhs[0] = mxCreateDoubleMatrix(RowA,ColB,mxREAL); //获取指向输出参数的指针 C= mxGetPr(plhs[0]); mexArrayAdd(RowA, ColA, A, B, C); }
最后
以上就是漂亮野狼最近收集整理的关于Matab与C混合编程 C_MEX函数编写的全部内容,更多相关Matab与C混合编程内容请搜索靠谱客的其他文章。
发表评论 取消回复