读了一些混合编程的程序,然后由于项目需要,写了一些代码,但并没有看过混合编程方面的书籍,故讲解的不够全面及深入。
在入门篇里讲解了环境的搭建及演示了一个hello word!程序:
#include <mex.h>
void mexFunction(int nlhs ,mxArray *plhs[] ,int nrhs, const mxArray *prhs[]){ mexPrintf("Hello word!");}程序很简单,但和我们平常写的C程序并不一样,
程序必须包含mex.h头文件。
C的入口函数为mexFunction相当于我们常写的main函数,此函数没有返回值,必须是void型。
nlhs 为函数输出的个数,plhs为函数输出值,
nrhs 为函数输入的个数,prhs为函数参数值。
举例:
如.m函数为 function [x,y]=shiftX(a,b,c)
则在写成C语言,nlhs为2,plhs为x,y,nrhs为3,prhs为a,b,c
C函数如何引用参数:
如果是数组则用mxGetPr(prhs[loc]) //loc是参数的位置,如是第一个参数则为0,如第二个则为1
如果是单个数值mxGetScalar(prhs[loc])
如果是多维数组并不能用Arr[i][j]的格式寻址,在参数在C里只是一维数组,
一维数组按列排列,C语言是按行排列的,
如[a b c d;e f g h]C语言在内存中是按a b c d e f g h排列,而matlab是按 a e b f c g d h排列的。
如果要变成C语言可Arr[i][j]索引的格式,可用for循环转化,下面举个三维的例子:
for(i=0;i<inM;i++) for(j=0;j<inN;j++) { inYr[i][j] = inY[j*inM+i]; inYg[i][j] = inY[inM*inN+j*inM+i]; inYb[i][j] = inY[2*inM*inN+j*inM+i]; }
转化前,只可以按inY[loc]索引,转换后可以按inYr[i][j]格式索引。
打印函数:
mexPrintf()相当于matlab的disp函数,
mexPrintf函数里需要打印的部分必须用""而不能用''
子函数的问题:
子函数有两种方式,一种采用return值得方式返回值
另一种方式为利用参数返回值,把需要return的值直接赋给形参。
多个.c文件的编译:
多个.c文件中只能存在一个mexFunction函数
可用mex ('a.c','b.c','d.c')的格式编译
下面是我写的C函数的一部分:
#include "mexSmoothL.h"#include "mexfunc.h" #define IN_Y prhs[0]#define IN_M prhs[1]#define IN_N prhs[2]#define IN_K prhs[3]#define OUT_L plhs[0]void mexFunction(int nlhs ,mxArray *plhs[] ,int nrhs, const mxArray *prhs[])
{ double *inY,*matmns; int i,j,k,l,m,n,inN,inM,inK,row,col; double **inYr,**inYg,**inYb,**maxt,**numk,***uk,****covk; double eye[3][3]={ {1,0,0},{0,1,0},{0,0,1}},**midv1,**midv2; inY = mxGetPr(IN_Y); inM = (int)mxGetScalar(IN_M); inN = (int)mxGetScalar(IN_N); inK = (int)mxGetScalar(IN_K); OUT_L=mxCreateDoubleMatrix(1,inN,mxREAL); //matmns = mxGetPr(plhs[0]); inYr=malloc2Ddouble(inM, inN); inYg=malloc2Ddouble(inM, inN); inYb=malloc2Ddouble(inM, inN); numk=malloc2Ddouble(inM, inN); uk=malloc3Ddouble(inM, inN,inK); covk=malloc4Ddouble(inM, inN,inK,inK); for(i=0;i<inM;i++) for(j=0;j<inN;j++) { inYr[i][j] = inY[j*inM+i]; inYg[i][j] = inY[inM*inN+j*inM+i]; inYb[i][j] = inY[2*inM*inN+j*inM+i]; } maxt=malloc2Ddouble(9, inK); midv1=malloc2Ddouble(inK, inK); midv2=malloc2Ddouble(inK, inK); matmns = malloc1Ddouble(inK); for(row = 0;row<inM;++row) for(col = 0;col<inN;++col) { l=0; for(i=max(0, col-RR);i<=min(inN-1, col+RR);i++) for(j=max(row-RR, 0);j<=min(inM-1, row+RR);j++) { maxt[l][0]=inYr[j][i]; maxt[l][1]=inYg[j][i]; maxt[l][2]=inYb[j][i]; l++; } numk[row][col]=l; mat_mns(maxt, matmns, l, inK); for(j=0;j<inK;j++) uk[row][col][j]=matmns[j]; mat_cov(maxt, midv1, l, 3); mat_add_mat(midv1, eye, epp/l, 3, 3); mat3_inv(midv1, midv2, 3); for(i=0;i<3;i++) for(j=0;j<3;j++) { covk[row][col][i][j] = midv2[i][j]; mexPrintf("%f ",midv2[i][j]); } }free(maxt);
free(matmns); }