zz MATLAB 与 C 语言混合编程接口:MEX 函数最简单示例之一

MATLAB是一种解释性语言,不需要编译,调试比较方便,但是缺点是速度慢。这一点在执行复杂的科学算法的时候体现极为明显。而C语言虽然相对比较复杂,但是执行效率很高,MATLAB很多内置函数都是用C写的。另外有时候很多算法已经已C语言的形式写好,于是我们会想到是否有方法将C语言代码与MATLAB连接起来。MATLAB提供一个C语言中的MEX函数库,可以实现以上功能。这里以一个最简单的例子来说明。

我们的目标是:用C语言写一个加法函数add(),在MATLAB中输入c=add(a,b)可以得到a与b的和。

这个示例是否有点白痴?c=a+b不就完了?这里只是一个示例而已,把最基本的环节解释清楚就够了。

我们要做的是

  1. 在MATLAB当目录中建立一个add.c文件;
  2. 用你熟知的C语言写一个add()函数;
  3. 利用mexFuncion()函数创建C与MATLAB的接口;
  4. 从MATLAB命令窗口中编译add.c文件为MEX文件;
  5. MATLAB命令窗口中使用add()函数。

建立add.c文件

这个文件被称为Source MEX-File

  1. 在当前文件夹窗口中新建一个脚本:右键单击空白处,选择New File,选择Script
  2. 重命名文件为add.c
  3. 用外部编辑器打开add.c

编辑add.c文件

MATLAB提供一个函数库,保存在mex.h中,所以文件一开始要将其include:

1
#include "mex.h"

然后用你熟知的C语言写一个函数吧

1
2
3
double add ( double x , double y ) {
    return x + y ;
}

这段代码被称作Computational Routine,就是真正的算法实现的地方。

然后我们来建立其与MATLAB的间接口。MEX函数库里有个mexFunction()函数,它相当于C语言中的main()函数。所以这里我们知道了MEX源文件没有main(),而是以一个mexFunction()代替。

mexFunction的参数是这样的:

1
2
3
void mexFunction ( int nlhs , mxArray *plhs [ ] , int nrhs , const mxArray *prhs [ ] ) {
    //这里是正文
}

其中nlhs (number of left-hand side) 是输出参数的个数,nrhs (number of right-hand side) 是输入参数的个数。例如对于c=add(a,b),有 nlhs=1,hrhs=2。

plhs[]与prhs[]都是指针数组,也就是说它是个数组,每个元素都是一个指针,这些指针指向的东东的类型是mxArray。那什么是mxArray呢?可以把他理解MATLAB中的矩阵,因为MATLAB中所有数据都是以矩阵的形式保存的。

先讲prhs[],就是输入的参数,prhs[0]指向a,prhs[1]指向b,但是注意不能用*(prhs[0])得到a的值。因为prhs[0]指向的东西的类型是mxArray(参数列表里看出),想把它的值以我们常用的数值形式赋给一个标量(Scalar),得使用mxGetScalar()函数转化一下:

1
2
3
    double a , b ;
    a = mxGetScalar (prhs [ 0 ] ) ;
    b = mxGetScalar (prhs [ 1 ] ) ;

plhs对应的输出的内容。plhs[0]这个指针指向输出的第一个参数,就是c=add(a, b)中的c了。记住这个c应该是以mxArray的类型出现的,为了得到mxArray类型的输出量,要使用mxCreateDoubleMatrix()函数,它创建一个指向mxArray类型的指针。

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

参数(1, 1, mxREAL)定义了对应c的尺寸类型,MATLAB中c是以1×1的实数矩阵形式报保存的。

而使用mxGetPr()函数可以得到plhs[0]指向的mxArray的第一个double类型的指针。

1
2
    double *c ;
    c = mxGetPr (plhs [ 0 ] ) ;

最后调用add()函数

1
    *c =add (a ,b ) ;

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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 , b ;
    a = mxGetScalar (prhs [ 0 ] ) ;
    b = mxGetScalar (prhs [ 1 ] ) ;

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

    double *c ;
    c = mxGetPr (plhs [ 0 ] ) ;

    *c =add (a ,b ) ;
}

编译add.c文件为MEX文件

在MATLAB命令窗口中输入

1
mex add. c

回车后MATLAB会调用编译器把源程序编译成为MEX文件。
注意如果是在MAC OS X下提示gcc 4.0 Command not found之类的错误信息,则需要安装Xcode

执行c=add(a,b)

在MATLAB命令窗口中输入

1
c=add ( 1, 2 )

回车后可以得到结果。

注: MATLAB 2010a 及以后版本使用了不同的 API,所以该文章适用于以前的版本。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值