matlab默认的程序文件是.m文件,但有很多情况下需要用matlab调用C语言程序,归纳起来有以几种情况:
1、matlab程序中的某模块非常耗时,改用C语言编写可以提高执行速度。
2、现有成熟算法已经用C语言编写完成,但是matlab程序需要调用其中的某一算法,但不想改写成为.m程序
3、从.m程序可以直接获取源代码,为了保护知识产权,作者希望只提供接口,和库函数,供使用者调用。类似于Windows系统动态链接库(.dll)
以上常见问题可以通过mex文件轻松解决。
什么是MEX文件呢?
以下内容摘自MEX文件百度百科(感觉写的比较全面):
MEX从字面上是MATLAB和Executable两个单词的缩写。 即:matlab可执行文件的缩写
.MEX文件是一种可在matlab环境中调用的C(或fortran)语言衍生程序,MEX文件的后缀名按32位/64位分别为.mexw32/.mexw64。
MEX文件是由C或Fortran语言编写的源代码,经matlab编译器处理而生成的二进制文件。它是可以被matlab解释器自动装载并执行的动态链接程序,类似windows下的dll文件。
MEX文件实现了一种其它语言与MATLAB的接口,通过MEX文件可以在MATLAB中像调用内嵌函数一样调用使用C语言和Fortran等语言编写的函数,实现了代码重用,同时也能提高MATLAB环境中数据处理的效率。
编写MEX文件之前需要配置matlab编译器,如何配置呢?
以下讲解的matlab所用版本为matlab R2009a,其他版本类似。“蓝色是文字是手动输入的,绿色文字是malab提示字符”
在matlab工作区中输入以下命令行:
mex -setup
matlab提示如下,是否定位已安装的编译器,此处选y
Would you like mexto locate installed compilers [y]/n? y
可选编译器列表如下:
Select a compiler:
[1] Lcc-win32 C 2.4.1 inF:matsyslcc
[2] Microsoft Visual C++ 6.0in F:Program FilesMicrosoft Visual Studio
[0]None
Compiler:1
此处我选择matlab自带编译器,所以我选择[1]."你也可以选择[2],使用VC6.0编译器",提示如下:
Please verify yourchoices:
Compiler: Lcc-win32 C2.4.1
Location:F:matsyslcc
Are these correct[y]/n? y
matlab让确认所选编译器路径是否正确。“我的matlab安装在F盘,lcc路径正确,所以我选择y”,提示如下:
Trying to update options file:C:UsersweiAppDataRoamingMathWorksMATLABR2009amexopts.bat
Fromtemplate: F:matbinwin32mexoptslccopts.bat
Done . . .
至此编译器配置完成。
MEX源代码如何编写?
mex的编译结果实际上就是一个带输出函数mexFunction的dll文件,所以写MEX程序其实就是写一个DLL程序。编写MEX程序的编辑器可以使用MATLAB的代码编辑器,也可使用自己的C++编辑器,如VS2008等。“推荐用VC编写,因为matlab代码编辑器无法调试.用VC编辑前,需要配置VC环境,将matlab目录下的..matextern配置到VC,包括引用文件inlucde,库文件lib,可执行文件matlab.
MEX文件格式:
#include "mex.h"
#inlude
void mexFunction ( int nlhs, mxArray *plhs[], int nrhs, constmxArray *prhs[] )
{
}
四个参数分别用来输出(left)和输入(right)数据: nlhs 输出参数个数,plhs输出参数指针(nrhs和prhs是输入参数相关的)。如,plhs[0]表示输出参数1,plhs[1]表示输出参数2,输入参数prhs用法类似。
注意:对输出和输入参数的操作都是通过指针的方式进行的。
注意:不要使用中文注释,否则可能会编译报错
操作输入数据:
对输入数据进行操作,需要通过MEX函数mxGetPr得到数据的指针地址。 mxGetM 和 mxGetN得到矩阵数据的行和列 (返回整数)。对于实矩阵,我们可以定义 double *M; 来对实矩阵数据操作。如:
double *M;
int m,n;
//指针指向第一个参数的数据地址
M = mxGetPr(prhs[0]);
m = mxGetM(prhs[0]);
n = mxGetN(prhs[0]);
MATLAB矩阵数据的存储顺序是"从上到下,从左到右"的,这点和Fortran是一样的。也就是说对于MATLAB的mx n的矩阵A。 A(1,1) 就是 *M,A(2,1) 就是 *(M+1) ,以此类推,A(i,j) 就是 *(M +m*(j-1) + (i-1)).
注意: MATLAB的指标从1开始,C的指标从0开始。
操作输出数据:
对于输出数据,需要首先用专门的mex函数分配内存空间,如:
plhs[0] = mxCreateDoubleMatrix(m,n, mxREAL); //生成m x n的实矩阵。
同输入数据一样,要对输出数据操作,我们也需要一个指向数据的指针变量,如
double *A;//注意,是一维指针,对指针A赋值,就是给返回值赋值
A = mxGetPr(plhs[0]);
MEX代码如何编译?
如编译链接C语言的MEX文件源程序,在MATLAB的控制窗口中输入:mextest.c在当前工作目录下生成一个名为test.mexw32的MEX文件
MEX文件如何使用?
运行:在MATLAB的控制窗口中输入
x=2;
y=test(x)
输出:y=4
test.c源代码如下:
#include
#include "mex.h"
void mexFunction( intnlhs, mxArray *plhs[],
int nrhs,const mxArray*prhs[] )
{
double*p_out;
doubleinput_data;
input_data=mxGetPr(prhs[0])[0];
plhs[0]=mxCreateDoubleMatrix(1,1, mxREAL);
p_out=mxGetPr(plhs[0]);
p_out[0]=2*input_data;
return;
}
发表评论 取消回复