首页 mex文件_实现调用C函数的接口

mex文件_实现调用C函数的接口

举报
开通vip

mex文件_实现调用C函数的接口 1 MEXMEXMEXMEX文件--------实现调用 CCCC函数的接口 如果我有一个用 C语言写的函数,实现了一个功能,如一个简单 的函数: double add(double x, double y) { return x + y; } 现在我想要在Matlab中使用它,比如输入: >> a = add(1.1, 2.2) 3.3000 要得出以上的结果,那应该怎样做呢? 解决方法之一是要通过使用MEX文件,MEX文件使得调用 C函 数和调用Matlab的内置函 数一样方便。MEX...

mex文件_实现调用C函数的接口
1 MEXMEXMEXMEX文件--------实现调用 CCCC函数的接口 如果我有一个用 C语言写的函数,实现了一个功能,如一个简单 的函数: double add(double x, double y) { return x + y; } 现在我想要在Matlab中使用它,比如输入: >> a = add(1.1, 2.2) 3.3000 要得出以上的结果,那应该怎样做呢? 解决方法之一是要通过使用MEX文件,MEX文件使得调用 C函 数和调用Matlab的内置函 数一样方便。MEX文件是由原 C代码加 上 MEX文件专用的接口函数后编译而成的。可以这样理解,MEX 文件实现了一种接口,它把在Matlab中调用函数 时输入的自变量通 过特定的接口调入了 C函数,得出的结果再通过该接口调回Matlab。 2 该特定接口的操作,包含在 mexFunction这个函数中,由使 用者具 体设定。 所以现在我们要写一个包含 add和 mexFunction的 C文件,Matlab 调用函数, 把函数中的自变量(如上例中的1.1和2.2)传给 mexFunction的一个参数,mexFunction把该值传给 add,把得出的结 果传回给 mexFunction的另一个参数,Matlab通过 该参数来给出在 Matlab语句中调用函数时的输出值(如上例中的 a)。 值得注意的是,mex文件是与平台有关的,以我的理解,mex文 件就是另类的动态链接库。在 matlab6.5中使用 mex -v 选项,你可 以看到最后 mex阶段有类似如下的信息: --> "del _lib94902.obj" --> "del "test.exp"" --> "del "test.lib"" 也就是说,虽然在 matlab6.5生成的是 dll文件,但是中间确实有 过 lib文件生成。 比如该 C文件已写好,名为 add.c。那么在Matlab中,输入: 3 >> mex add.c 就能把 add.c 编译为 MEX 文件(编译器的设置使用指令 mex -setup),在Windows中,MEX文件类型为 mexw32,即现在我们得 出 add.mexw32文件。现在,我们就可以像调用M函数那样调用 MEX 文件,如上面说到的例子。所以,通过MEX文件,使用 C函数就和 使用M函数是一样的了。 我们现在来说mexFunction怎样写。 mexFunction的定义为: void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*....................................*/ } 4 可以看到,mexFunction是没返回值的,它不是通过返回值把结果 传回Matlab的,而是通过对参数 plhs的赋值。mexFunction的四个参 数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时: >> b = 1.1; c = 2.2; >> a = add(b, c) mexFunction四个参数的意思为: nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量, 即 a。 nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变 量,即 b和 c。 plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。 因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向 的结果会赋值给 a。 prhs和 plhs类似,因为右手面有两个自变量,即该数组有两个指 针,prhs[0]指向了 b,prhs[1]指向了 c。要注意 prhs是 const的指针数 5 组,即不能改变其指向内容。 因为 Matlab最基本的单元为 array,无论是什么类型也好,如有 double array、cell array、 struct array……所以 a,b,c都是 array,b = 1.1 便是一个1x1的 double array。而在 C 语言中,Matlab的 array 使用 mxArray类型来表示。所以就不难明白为什么 plhs和 prhs都是指向 mxArray类型 的指针数组。 完整的 add.c如下: #include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的 C函数 double add(double x, double y) { return x + y; } 6 // MEX文件接口函数 void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[]) { double *a; double b, c; plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); a = mxGetPr(plhs[0]); b = *(mxGetPr(prhs[0])); c = *(mxGetPr(prhs[1])); *a = add(b, c); } mexFunction的内容是什么意思呢?我们知道,如果这样调用函数 时: >> output = add(1.1, 2.2); 7 在未涉及具体的计算时,output的值是未知的,是未赋值的。所 以在具体的程序中,我们建 立一个1x1的实 double 矩阵(使用 mxCreateDoubleMatrix函数,其返回指向刚建立的 mxArray的指针), 然后令 plhs[0]指向它。接着令指针 a指向 plhs [0]所指向的 mxArray 的第一个元素(使用 mxGetPr函数,返回指向 mxArray的首元素的 指针)。同样地,我们把 prhs[0]和 prhs [1]所指向的元素(即1.1和2.2) 取出来赋给 b和 c。于是我们可以把 b和 c作自变量传给函数 add, 得出给果赋给指针 a所指向的 mxArray中的 元素。因为 a是指向 plhs[0]所指向的 mxArray的元素,所以最后作输出时,plhs[0]所指向 的 mxArray赋值给 output,则 output便是已计算好的结果了。 上面说的一大堆指向这指向那,什么 mxArray,初学者肯定都会 被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看 多练。 实际上 mexFunction是没有这么简单的,我们要对用户的输入自 变量的个数和类型进行测试,以确保输入正确。如在 add函数的例子 中,用户输入 char array便是一种错误了。 8 从上面的讲述中我们 总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf 出,MEX文件实现了一种接口,把 C 语言中的计算结果适当地返回给 Matlab罢了。当我们已经有用 C编 写的大型程序时,大可不必在 Matlab里重写,只写个接口,做成 MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环), 可通过MEX文件用 C语言实现,以提高计 算速度。 以上是对 mex文件的初步认识,下面详细介绍如何用 c语言编写 mex文件: 1 为什么要用 C语言编写MEX文件 MATLAB是矩阵语言,是为向量和矩阵操作设计的,一般来说, 如果运算可以用向量或矩阵 实现,其运算速度是非常快的。但若运 算中涉及到大量的循环处理,MATLAB的速度的令人难以忍受的。 解决方法之一为,当必须使用 for循环时,把它写为 MEX文件,这 样不必在每次运行循环中的语句时MATLAB都对它们进行解释。 2 编译器的安装与配置 要使用 MATLAB 编译器,用户计算机上应用事先安装与 MATLAB适配的以下任何一种 ANSI C/C++编译器: 5.0、6.0版的MicroSoft Visual C++(MSVC) 5.0、5.2、5.3、5.4、5.5版的 Borland C++ 9 LCC(由MATLAB自带,只能用来产生MEX文件) 下面是安装与配置 MATLAB编译器应用程序 MEX的设置的步 骤: (1)在MATLAB命令窗口中运行mex –setup,出现下列提示: Please choose your compiler for building external interface (MEX) files: Would you like mex to locate installed compilers [y]/n? (2)选择 y,MATLAB将自动搜索计算机上已安装的外部编译器的类 型、版本及所在路径,并列出来让用户选择: Select a compiler: [1] Borland C++Builder version 6.0 in C:\Program Files\Borland [2] Digital Visual Fortran version 6.0 in C:\Program Files\Microsoft Visual Studio [3] Lcc C version 2.4 in D:\MATLAB6P5P1\sys\lcc [4] Microsoft Visual C/C++ version 6.0 in C:\Program 10 Files\Microsoft Visual Studio [0] None Compiler: (3)选择其中一种(在这里选择了3),MATLAB让用户进行确认: Please verify your choices: Compiler: Lcc C 2.4 Location: D:\MATLAB6P5P1\sys\lcc Are these correct?([y]/n): (4)选择 y,结束MATLAB编译器的配置。 3 一个简单的MEX文件例子 【例1】用 m文件建立一个1000×1000的 Hilbert矩阵。 11 tic m=1000; n=1000; a=zeros(m,n); for i=1:1000 for j=1:1000 a(i,j)=1/(i+j); end end toc 在 matlab中新建一个Matlab_1.cpp 文件并输入以下程序: 12 #include "mex.h" //计算过程 void hilb(double *y,int n) { int i,j; for(i=0;i> mex Matlab_2.cpp >> clear >> a=magic(5) a = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9 >> [y,z,w]=Matlab_2(5) ??? Undefined function or variable 'y'. a = 34 48 2 16 30 23 46 10 14 28 32 8 12 26 40 44 20 24 38 42 6 22 36 50 4 18 y = 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 z = 0.8333 -0.1667 -0.1667 0.2236 0.4472 -0.1667 0.8333 -0.1667 0.2236 0.4472 -0.1667 -0.1667 0.8333 0.2236 0.4472 -0.5000 -0.5000 -0.5000 0.2236 0.4472 24 0 0 0 -0.8944 0.4472 w = -1 0 0 0 0 0 -1 0 0 0 0 0 -1 0 0 0 0 0 -1 0 0 0 0 0 4 由上面可以看出,K5的特征值为–1和4,其中–1是四重根。 MATLAB提供了 mexGetVariable、mexPutVariable函数,以实现MEX 空间与其它空间交换数据的任务,具体可以参看MATLAB帮助文档。 5.4建立二维双精度矩阵函数mxCreateDoubleMatrix 其格式具体如下: #include "matrix.h" 25 mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag); 其中 m代表行数,n代表列数,ComplexFlag可取值 mxREAL 或 mxCOMPLEX。如果创建的矩阵需要虚部,选择 mxCOMPLEX,否 则选用 mxREAL。 类似的函数有: mxCreateCellArray 创建 n维元胞 mxArray mxCreateCellMatrix 创建二维元胞mxArray mxCreateCharArray 创建 n维字符串 mxArray mxCreateCharMatrix FromStrings 创建二维字符串mxArray mxCreateDoubleMat rix 创建二维双精度浮点 mxArray mxCreateDoubleScal ar 创建指定值的二维精度浮 点 mxArray mxCreateLogicalArr ay 创建 n维逻辑 mxArray, 初值为 false mxCreateLogicalMat rix 创建二维逻辑 mxArray, 初值为 false mxCreateLogicalScal 创建指定值的二维逻辑 26 ar mxArray mxCreateNumericAr ray 创建 n维数值 mxArray mxCreateNumericM atrix 创建二维数值 mxArray, 初值为0 mxCreateScalarDoub le 创建指定值的双精度 mxArray MxCreateSparse 创建二维稀疏mxArray mxCreateSparseLogi calMatrix 创 建 二 维 稀 疏 逻 辑 mxArray MxCreateString 创建指定字符串的1 n 的 串 mxArray mxCreateStructArray 创建 n维架构 mxArray mxCreateStructMatri x 创建二维架构mxArray 5.5 获取行维和列维函数mxGetM、mxGetN 其格式如下: 27 #include "matrix.h" int mxGetM(const mxArray *array_ptr); int mxGetN(const mxArray *array_ptr); 与之相关的还有: mxSetM:设置矩阵的行维 mxSetN:设置矩阵的列维 5.6 获取矩阵实部和虚部函数mxGetPr、mxGetPi 其格式如下: #include "matrix.h" double *mxGetPr(const mxArray *array_ptr); double *mxGetPi(const mxArray *array_ptr); 与之相关的函数还有: 28 mxSetPr:设置矩阵的实部 mxSetPi:设置矩阵的虚部 【例3】实现字符串的倒序输出。 #include "mex.h" void revord(char *input_buf,int buflen,char *output_buf) { int i; //实现字符串倒序 for(i=0;i1) mexErrMsgTxt("Too many output arguments."); //检查输入参数是否是一个字符串 if(mxIsChar(prhs[0])!=1) mexErrMsgTxt("Input must be a string."); //检查输入参数是否是一个行变量 if(mxGetM(prhs[0])!=1) 30 mexErrMsgTxt("Input must a row vector."); //得到输入字符串的长度 buflen=(mxGetM(prhs[0])*mxGetN(prhs[0]))+1; //为输入和输出字符串分配内存 input_buf=mxCalloc(buflen,sizeof(char)); output_buf=mxCalloc(buflen,sizeof(char)); //将输入参量的 mxArray结构中的数值拷贝到 C类型字符串 指针 status=mxGetString(prhs[0],input_buf,buflen); if(status!=0) mexWarnMsgTxt("Not enough space. String is truncated."); //调用 C程序 revord(input_buf,buflen,output_buf); plhs[0]=mxCreateString(output_buf); } 31 这个程序中需要注意的地方是 mxCalloc函数,它代替了标准 C 程序中的 calloc函 数用于动态分配内存,而 mxCalloc函数采用的是 MATLAB的内存管理机制,并将所有申请的内存初始化为0,因此凡 是 C代码需要使用 calloc函 数的地方,对应的 Mex文件应该使用 mxCalloc函数。同样,凡是 C代码需要使用 realloc函数的地方,对 应的Mex文件应该使用 mxRealloc函数。 在MATLAB命令窗口中对 revord.cpp程序代码编译链接: >> mex revord.cpp 在MATLAB命令窗口中对 C-MEX文件 revord.dll进行测试: >> x='I am student.'; >> revord(x) ans = .tneduts ma I 32 终于写完了,相信大家对 mex文件应该有点熟悉了,具体还要到 实际应用中慢慢体会。
本文档为【mex文件_实现调用C函数的接口】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_937910
暂无简介~
格式:pdf
大小:182KB
软件:PDF阅读器
页数:32
分类:工学
上传时间:2014-03-12
浏览量:28