设为首页 加入收藏

TOP

Matlab调用C程序(一)
2015-01-21 11:08:09 来源: 作者: 【 】 浏览:67
Tags:Matlab 调用 程序

Matlab是矩阵语言,如果运算可以用矩阵实现,其运算速度非常快。但若运算中涉及到大量循环,Matlab的速度令人难以忍受的。当必须使用for循环且找不到对应的矩阵运算来等效时,可以将耗时长的函数用C语言实现,并编译成Mex文件,Matlab便可以像调用内建函数一样调用C编写的函数。Mex文件其实是一种动态链接库,旧版本Matlab可以直接调用.dll,新版本要调用.mexw32或.mexw64文件。

编译过程需要C语言编译器,在Matlab中键入mex –setup进行安装与配置。

MEX文件的源代码组成

(1)功能子程序。该过程包含了Mex文件实现计算功能的代码,是标准的C语言子程序。

(2)入口子程序。该过程提供功能子程序与Matlab之间的接口,以mexFunction函数实现。注意,入口过程的名称必须是mexFunction,并且包含四个参数,即

void mexFunction(int nlhs,mxArray*plhs[],int nrhs,const mxArray *prhs[]);

nrhs(left hand side): 输入参数的个数;

prhs是一个输入数组,其内容为指针,指向mxArray类型的数据(MATLAB中所有数据都是以矩阵的形式mxArray保存的)。

nlhs, plhs含义类似。

具体地,若在Matlab中执行[a,b]=test(c,d,e) ,则nlhs=2, nrhs=3,prhs[0]指向c,prhs[1]指向d,prhs[2]指向e(可以理解为:prhs[0]=&c, prhs[1]=&d, prhs[2]=&e),注意prhs是const指针数组,故不能改变其指向内容;函数返回时将plhs[0],plhs[1]指向的内容赋给a,b(可以理解为a=*plhs[0], b=*plhs[1])。

?

:新建add.c,源码如下:

#include mex.h  
double add(double x, double y)
{
    return x + y;
} 
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);
}

将add.c拷贝至Matlab当前目录,执行mex add.c,生成add.mexw64,该文件实现求和功能。此时便可在Matlab中调用该函数:

>> output = add(1.1, 2.2);

分析:

#include mex.h

Mex源文件必须包含mex.h,该头文件提供了大量Matlab与C(或Fortran)语言的之间的接口函数,函数前缀有mex-和mx-两种,带mx-前缀的大多是对mxArray数据进行操作的函数,如mxIsDouble,mxCreateDoubleMatrix等;而带mex-前缀的则大多是与Matlab环境进行交互的函数,如mexPrintf,mexErrMsgTxt等。具体可参考Apiref.pdf。

plhs[0] = mxCreateDoubleMatrix(1, 1,mxREAL);

建立一个1x1的double类型的矩阵,返回刚建立的mxArray的地址,赋给指针plhs[0];

a = mxGetPr(plhs[0]);

返回指针plhs[0]所指向矩阵的第一个实数的地址,并赋给a;

b = *(mxGetPr(prhs[0]));

获取指针prhs[0]指向矩阵的第一个实数,并赋给b;

*a = add(b, c);

调用C程序add,计算b,c之和并赋给a指向的内容;

例:新建myhilb.c,源码如下:

#include mex.h
void myhilb(double *y,int n)
{
    int i,j;
    for(i=0;i
  
   

将myhilb.c拷贝至Matlab当前目录,执行mex myhilb.c,生成myhilb.mexw64,该文件实现了计算Hilbert矩阵的功能(Hilbert矩阵:H(i,j)=1/(i+j-1))。

此时便可在Matlab中调用该函数:

>> output = myhilb (6);

分析:

mexFunction中进行了参数检查,函数mexErrMsgTxt显示出错信息后即退回到MATLAB。

mxGetScalar:获取输入矩阵第一个元素的实数部分;mxGetM:获取矩阵的行数。

为了测试一下Mex文件与m文件的速度差异,编写m文件并运行之:

tic
m=10000;
a=zeros(m,m);
for i=1:m
     for j=1:m
         a(i,j)=1/(i+j);
     end
end
toc

结果:Elapsed time is3.620924 seconds.

接着运行Mex文件

?

?

tic
output = myhl(10000);
toc

?

结果:Elapsed timeis 0.730596 seconds.

可以看出Mex文件与M文件速度差异很大。

?

VS2010生成Mex文件(本人64位操作系统

上述利用Matlab编译生成Mex文件,同样也可以使用VS2010生成Mex文件,只不过需要对VS环境进行配置,过程如下:

1、 新建一个win32 控制台的dll 空项目”myhilb”;

2、 新建源文件myhilb.c,将上述myhilb.c内容拷进即可;

3、 添加.def文件,内容为:

LIBRARY

EXPORTSmexFunction

4、 配置项目属性, 打开项目属性配置页:

(1)C/C++—>常规—>附加包含目录,输入matlab下安装目录下externinclude

本人输入E:Matlab2010Installexterninclude

(2)链接器->常规—>附加库目录,输入matlab下安装目录下externlibwin64microsoft

本人输入E:Matlab2010Installexternlibwin64microsoft

(3)连接器 ->输入->附加依赖项,输入

libmx.lib

libeng.lib

libmat.lib

libmex.lib

(4)链接器->常规—>输出文件,输入$(OutDir)$(TargetName).mexw64(若此处不更改,可在生成dll文件后将后缀名改为mexw64即可,这也验证了Mex实际上就是DLL,只是后缀名不同罢了)

(5)链接器->高级—>目标计算机,设为MachineX64(32位系统不用更改)

设置好点击应用,执行了(5)的64位系统还需要在执行:

生成—>配置管理器—>活动解决平台,改为x64

5、按F7编译工程,会在Debug下生成.mexw64文件,如下图:

\

VS中单步调试Mex文件

在Matlab环境下使用 mex –g myhilb.c命令进行调试,但无法加断点进行单步调试,故需转到VS环境下调试。

不管是利用

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言学习入门 (九) typedef 关键.. 下一篇数据结构(C实现)------- 图的邻..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: