Math 版 (精华区)

发信人: ysc (bajie), 信区: Math
标  题: 用c编写mex程序 [part 3] (转信)
发信站: 哈工大紫丁香 (Sun Oct 22 09:01:34 2000), 转信

发信人: fasiondog (乱了), 信区: MathTools       
发信站: BBS 水木清华站 (Sun Apr  4 10:59:00 1999)

发信人: dodoo (虚怀), 信区: Programming
标  题: 用C编写mex程序  [PART 3]
  分析hello.c,可以看到程序的结构是十分简单的,整个程序由一个接口子过程
mexFunction构成。前面提到过,Matlab的mex函数有一定的接口规范,就是指这
nlhs:输出参数数目
plhs:指向输出参数的指针
nrhs:输入参数数目
例如,使用 [a,b]=test(c,d,e) 调用mex函数test时,传给test的这四个参数分别是2,
plhs,3,prhs。其中:
prhs[0]=c

prhs[1]=d

prhs[2]=e

当函数返回时,将会把你放在plhs[0],plhs[1]里的地址赋给a和b,达到返回数据的目

的。


  细心的你也许已经注意到,prhs[i]和plhs[i]都是指向类型mxArray类型数据的指针。

这个类型是在mex.h中定义的,事实上,在Matlab里大多数数据都是以这种类型存在。当

然还有其他的数据类型,可以参考Apiguide.pdf里的介绍。


  为了让大家能更直观地了解参数传递的过程,我们把hello.c改写一下,使它能根据输

入参数的变化给出不同的屏幕输出:


//hello.c 2.0


#include "mex.h"

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

{

 int i;

 i=mxGetScalar(prhs[0]);

 if(i==1)

  mexPrintf("hello,world!\n");

 else

  mexPrintf("大家好!\n");

}


  将这个程序编译通过后,执行hello(1),屏幕上会打出:

hello,world!

  而hello(0)将会得到:

大家好!


现在,程序hello已经可以根据输入参数来给出相应的屏幕输出。在这个程序里,除了用

到了屏幕输出函数mexPrintf(用法跟c里的printf函数几乎完全一样)外,还用到了一

个函数:mxGetScalar,调用方式如下:

i=mxGetScalar(prhs[0]);

  "Scalar"就是标量的意思。在Matlab里数据都是以数组的形式存在的,mxGetScalar的

作用就是把通过prhs[0]传递进来的mxArray类型的指针指向的数据(标量)赋给C程序里

的变量。这个变量本来应该是double类型的,通过强制类型转换赋给了整形变量i。


  既然有标量,显然还应该有矢量,否则矩阵就没法传了。看下面的程序:


//hello.c 2.1


#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[],

     int nrhs, const mxArray *prhs[])

{

 int *i;

 i=mxGetPr(prhs[0]);

 if(i[0]==1)

  mexPrintf("hello,world!\n");

 else

  mexPrintf("大家好!\n");

}


  这样,就通过mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的

指针。


  但是,还有个问题,如果输入的不是单个的数据,而是向量或矩阵,那该怎么处理呢

?通过mxGetPr只能得到指向这个矩阵的指针,如果我们不知道这个矩阵的确切大小,就

没法对它进行计算。


  为了解决这个问题,Matlab提供了两个函数mxGetM和mxGetN来获得传进来参数的行数

和列数。下面例程的功能很简单,就是获得输入的矩阵,把它在屏幕上显示出来:

//show.c 1.0


#include "mex.h"

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


{

 double *data;

 int M,N;

 int i,j;



 data=mxGetPr(prhs[0]); //获得指向矩阵的指针

 M=mxGetM(prhs[0]); //获得矩阵的行数

 N=mxGetN(prhs[0]); //获得矩阵的列数


 for(i=0;i<M;i++)

 {

  for(j=0;j<N;j++)

   mexPrintf("%4.3f  ",data[j*M+i]);

  mexPrintf("\n");

 }

}


  编译完成后,用下面的命令测试一下:


  a=1:10;

  b=[a;a+1];

  show(a)

  show(b)


  需要注意的是,在Matlab里,矩阵第一行是从1开始的,而在C语言中,第一行的序数

为零,Matlab里的矩阵元素b(i,j)在传递到C中的一维数组大data后对应于data[j*M+i]




--

※ 来源: 心网 cag.seu.edu.cn [FROM: 202.119.30.69]

--

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: ysc.bbs@smth.org]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.179毫秒