在C语言的MEX文件中,参数nlhs和nrhs包含输出和输入变量的数目,借助于这两个参数,MEX文件被调用。参数plhs和prhs是包含指向MEX文件输出和输入变量的指针的向量,prhs是长度为nrhs的输入变量的指针数组,plhs是长度为nlhs的输出变量的指针数组。比如从MATLAB命令窗口来调用一个MEX文件: x=fun(y,z);
则MATLAB编译器使用下面的变量来调用mexFunction: nlhs=1 nrhs=2 plhs=(pointer)->/*unassigned*/ prhs=(pointer)->y (pointer)->z
plhs指向只有一个元素的C语言数组,并且这个元素为空指针。prhs指向含有两个元素的C语言数组,其中第一个元素指向mxArray型变量Y,第二个元素指向mxArray型变量Z。
这里,plhs指向空的数组是由于输出x在子程序执行前尚未产生,入口程序的作用就是创建输出数组并分配指针plhs[0]指向该数组。如果plhs[0]没有赋值,MATLAB将给出输出变量没有赋值的警告信息。
三、C语言程序MEX文件实例
MATLAB 5 API提供了一系列程序来处理MATLAB所支持的各种数据类型,每一种数据类型都有对应函数共你使用来处理对应的数据。下面给出一个简单的C语言程序和与之对应的MEX文件代码,该程序的功能是将标量x加倍。
C语言程序如下:
#include "math.h" void timestwo(double y[], double x[]) { y[0]=2.0*x[0]; return; }
下面是与C语言程序功能相同的MEX文件: #include "mex.h" void timestwo(double y[], double x[]) { y[0]=2.0*x[0]; } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *x, *y; int mrows, ncols; /*检查正确的参数数目*/ if(nrhs!=1){ mexErrMsgTxt("需要一个输入参数."); } else if(nlhs>1){ mexErrMsgTxt("输出参数太多."); } /*输入变量必须是非复数类型的标量*/ mrows=mxGetM(prhs[0]); ncols=mxGetN(prhs[0]); if(!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows==1 && ncols==1)){ mexErrMsgTxt("输入变量必须是非复数类型的标量."); } /*为返回参数创建矩阵*/ plhs[0]=mxCreateDoubleMatrix(mrows, ncols, mxREAL); /*分配输入输出参数的指针*/ x=mxGetPr(prhs[0]); y=mxGetPr(plhs[0]); /*调用timestwo子函数*/ timestwo(y, x); }
|
C语言是在编译的时候检查函数参数。MATLAB可以在M函数中传递任意数量和类型的参数,MEX文件也是如此,不过在程序中必须可靠地处理输入输出参数的数目。如果将上面的MEX文件命名为timestwo.c,就可以对它进行编译和链接,在MATLAB命令窗口下输入: mex timestwo.c
这是产生MEX文件timestwo.***所必需的步骤,该文件的扩展名所运行的系统平台的类型。Windows系统下,扩展名为dll。此时,就可以象调用M函数一样调用timestwo了。
在MATLAB命令窗口中输入: x=2; y=timestwo(x); 就可以得到: y=4;
四、小 结
MEX文件虽然具有较强大的功能,但并不是对所有的应用都恰当。MATLAB是一个高效率的编程系统,特别适合于工程计算、系统仿真等应用。它的最大优点就是将人们从繁杂的程序中解放出来。因此,能够用M文件完成的程序,应尽量使用MATLAB编写,除非遇到必须使用MEX文件的情况。
MATLAB的应用编程接口是一个功能强大的系统,除了调用C或Fortran程序,还可以实现从MATLAB环境中输入输出数据、在MATLAB中和其他程序建立客户/服务器关系等功能。 |