C-MEX程序编写学习笔记.doc_第1页
C-MEX程序编写学习笔记.doc_第2页
C-MEX程序编写学习笔记.doc_第3页
C-MEX程序编写学习笔记.doc_第4页
C-MEX程序编写学习笔记.doc_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C-MEX程序编写学习笔记胡荣春 2006-10-111 MEX文件简介在MATLAB中可调用的C或Fortran语言程序称为MEX文件。MATLAB可以直接把MEX文件视为它的内建函数进行调用。MEX文件是动态链接的子例程,MATLAB解释器可以自动载入并执行它。MEX文件主要有以下用途:1 对于大量现有的C或者Fortran程序可以无须改写成MATLAB专用的M文件格式而在MATLAB中执行。2 对于那些MATLAB运算速度过慢的算法,可以用C或者Frotran语言编写以提高效率。2 一个MEX文件例子#include mex.h /* timestwo.c本MEX文件的目的是实现timestwo的功能*/void timestwo(double y, double x) y0 = 2.0*x0; /*下面这个mexFunction的目的是使MATLAB知道如何调用这个timestwo函数*/void mexFunction( int nlhs, mxArray *plhs, int nrhs, const mxArray *prhs ) /* nlhs是MATLAB命令行方式下输出参数的个数; *plhs是MATLAB命令行方式下的输出参数; nrhs是MATLAB命令行方式下输入参数的个数; *prhs是MATLAB命令行方式下的输入参数; */ double *x,*y; /double指针类型不能改变!int mrows,ncols; /* Check for proper number of arguments. */ if(nrhs!=1) mexErrMsgTxt(One input required.); else if(nlhs1)mexErrMsgTxt(Too many output arguments); /* 在MATLAB命令行方式下,本MEX文件的调用格式是y=timestwo(x) 输入参数(x)个数1,输出参数(y)个数1,所以在程序一 开始就检查nrhs是否1以及nlhs是否1(因为MATLAB有一个缺省 输出参数ans,所以nlhs可以=0 */mrows = mxGetM(prhs0); /* 获得输入矩阵的行数 */ ncols = mxGetN(prhs0); /* 获得输入矩阵的列数 */ if( !mxIsDouble(prhs0) | mxIsComplex(prhs0) | !(mrows=1 & ncols=1) )mexErrMsgTxt(Input must be a noncomplex scalar double.); /* 判断输入矩阵是否是double类,以及它是否只包括单个元素 */ /* 为输出创建一个矩阵,显然这个矩阵也应该是1x1的 */ plhs0 = mxCreateDoubleMatrix(mrows,ncols, mxREAL); x = mxGetPr(prhs0); /* 获得指向输入/输出矩阵数据的指针 */y = mxGetPr(plhs0); timestwo(y,x); /* 调用C 函数timestwo(y,x) */把上面这个文件timestwo.c编辑完成后,在matlab命令行里输入:mex timestwo.cmatlab会提示你选择一个编译器进行编译,如果安装了VC,则选择VC+即可。编译完成后会在同一目录下生成同名的动态链接库文件timestwo.dll。此后再输入“mex *.c”编译mex文件时将不再提示用户选择编译器,而自动选择默认的编译器编译。若想改变编译器进行编译,可输入“mex timestwo.c setup”。编译完成后即可使用此动态链接库了。在MATLAB命令行下输入:x = 2; y = timestwo(x) 将会显示:y = 43 MEX文件格式详解首先编制自己的C算法程序,紧跟着定义mexFunction函数,mexFunction的定义法唯一,它只能是如下形式: void mexFunction( int nlhs, mxArray *plhs, int nrhs, const mxArray *prhs ) 其名称和参数类型不许有任何改变,在mexFunciton函数中可以调用你刚定义好的C 程序。 3.1 参数定义以上面的timestwo.c文件为例,当编译完成后在matlab命令行输入“y = timestwo(x)”时,matlab便随即加载timestwo.dll动态链接库文件。timestwo.dll加载完成后首先执行mexFunciton函数,并把输入参数x的值“2”传递给prhs0,输入参数的个数“1”传递给plhs。由于matlab里的变量都是以double类型存储的,故mex程序里所有输入输出参数对应的C类型均应为double。这也是为什么上例中定义“double *x,*y;”必须为double指针类型的原因。而且还要注意,必须是double指针,不能仅为double。3.2 输入输出参数检查接下来可以做输入参数的检查,确定输入参数的个数是否符合定义,否则给出错误提示信息。3.3 参数挂接参数检查完成以后就是对应输入输出参数的挂接(一时想不到更好的词,此处暂借用“挂接”一词表达如下所述的意思):/* 为输出创建一个矩阵,显然这个矩阵也应该是1x1的 */ plhs0 = mxCreateDoubleMatrix(mrows,ncols, mxREAL); x = mxGetPr(prhs0); /* 获得指向输入/输出矩阵数据的指针 */y = mxGetPr(plhs0); 这里首先给输出参数创建了一个矩阵。注意,不论输出的是一个矩阵还是一个标量,都必须为所有的输出参数创建单独的矩阵。如果是标量,则创建的时候把行和列都设为1即可:mxCreateDoubleMatrix(1,1, mxREAL);之所以这样做的原因是matlab里面每个变量都是以矩阵形式存在的。prhs和plhs是不能直接在程序中使用的,必须要定义对应的指针变量。故而要对接口参数的指针和程序中使用参数的指针进行挂接,也就是“x = mxGetPr(prhs0);”语句所做的工作。看到这里就应该明白为什么void mexFunction函数里面所有的输入输出参数都必须定义为double指针的原因了吧。因为所有定义的参数必须要和prhs、plhs进行挂接。3.4 调用功能函数参数挂接完成以后就可以调用自己编写的功能函数了:timestwo(y,x); /* 调用C 函数timestwo(y,x) */这里需要注意,调用的输入参数与定义的参数要相符。如timestwo()函数的定义如下:void timestwo(double y, double x)两个参数均为指针类型,故调用的时候“timestwo(y,x);”输入的是“y,x”两个指针。而如果timestwo()函数的定义为:void timestwo(double y, double x)则说明输入参数x应该为double类型的变量,这时的输入参数可写为:timestwo(y,x0);3.5 功能函数的编写功能函数的编写取决于用户要完成的功能。这里值得提出来说明的有以下2点:(1) 功能函数名和最终在matlab里调用的函数名没有直接联系,而只于mexFunction里调用的函数名有关系。Matlab调用的函数名取决于最后生成的dll文件名,而这个文件名可以任意更改(但首字母不能为数字)。(2) 功能函数没有返回值,是void类型,而整个dll模块最终返回给matlab的输出参数是包含在功能函数的输入参数中的。由前面介绍的输入输出参数需要挂接的原因,故功能函数的输入参数中对应的最终输出参数必须定义为double指针类型,如:“void timestwo(double y, double x)”。其中y是最终的输出参数,必须为double指针类型,而从matlab里传来的输入参数,则视情况而定是否需要定义为指针类型。3.6 第二个MEX文件例子这个例子是完成dijkstra最短路径算法的程序。#include mex.h /* 求网络中所有节点到指定节点的最短路,Dijkstra算法*/#define INFN 1000#define INFI 10000void f_dijkstra_all(double *w, double *D, unsigned long n, unsigned long p) unsigned long i,j,wtmp,pnew,nu=n-1,np=1;/np为已知距离节点数,nu为未知距离节点数,IDp为已知节点ID unsigned long IDuINFN, IDpINFN; /未知节点IDu, 已知节点IDp p-; IDp0=p; for (i=0;in;i+) wi=Dn*i+p; if ( ip ) IDui=i; else IDui=i+1; while (nu) wtmp=INFI; for (i=0;inu;i+) for (j=0;jnp;j+) if ( wIDpj+D n*IDpj+IDui wIDui ) wIDui=wIDpj+D n*IDpj+IDui ; if ( wIDuiINFI & wIDui wtmp ) wtmp=wIDui; pnew=i; if ( wtmpINFI ) IDpj=IDupnew; np+; for (i=0;i=pnew ) IDui=IDui+1; nu-; else nu=0; /*下面这个mexFunction的目的是使MATLAB知道如何调用这个函数*/ void mexFunction( int nlhs, mxArray *plhs, int nrhs, const mxArray *prhs ) if(nrhs!=3) mexErrMsgTxt(Three input required.); else if(nlhs1)mexErrMsgTxt(Too many output arguments); /mrows = mxGetM(prhs0); /* 获得输入矩阵的行数 */ ncols = mxGetN(prhs0); /* 获得输入矩阵的列数 */ if ( mxIsComplex(prhs0) )mexErrMsgTxt(Input must be a noncomplex.); /*判断输入矩阵是否为复数*/ plhs0 = mxCreateDoubleMatrix(1,ncols, mxREAL); /* 为输出创建一个矩阵*/ D = mxGetPr(prhs0); /* 获得指向输入/输出矩阵数据的指针 */ n = mxGetPr(prhs1); p = mxGetPr(prhs2); w = mxGetPr(plhs0);f_dijkstra_all(w, D, n0, p0); /* 调用C 函数*/ 4 补充说明在编写功能函数时,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论