#include "mex.h"
#include<math.h>

struct POINT
{
double x;
double y;
};

double CMoment(double * Data,int M,int N,double p ,double q, POINT center)
{
double ** Mat;
double cx,cy;

double tx,ty,m;
int i,j;

// 传过来的数据Data是按照先列后行的顺寻排列的。
for(i=0;i<N;i++)
Mat[i]=&Data[i*M];

// 此时Mat[i][j]是指第i列第j行
mexPrintf("c.x=%.0f,c.y=%.0f\n",center.x,center.y);

// mexErrMsgTxt("error");
cx = center.x;
cy = center.y;
cy = M+1-cy;

for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
mexPrintf("%0.f\t",Mat[i][j]);
mexPrintf("\n");
}

m=0;
for(i=0;i<N;i++)
for(j=0;j<M;j++)
{
tx=i+1-cx;
ty=j+1-cy;
m += Mat[i][j] * pow (tx,p) * pow (ty,q);
mexPrintf("Mat[%d][%d] = %.0f\t tx = %.0f ty = %.0f\t>>m = %.1f\n",i,j,Mat[i][j],tx,ty,m);
}
return m;
}

// matlab的接口是:
// function m = CMoments(Data,p,q,center);
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
double *m;
double *Data;
mwSize nArg;
int M,N;
double p,q;
POINT CCenter,CPow;

plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
m = mxGetPr(plhs[0]);
*m = mxGetNaN();

if(nrhs!=4)
mexErrMsgTxt("The number of inputs is not correct");

nArg = mxGetNumberOfDimensions(prhs[0]);
if(nArg!=2)
mexErrMsgTxt("error:The Dimension of the first argument is not correct!\n");

M=(int)mxGetM(prhs[0]);
N=(int)mxGetN(prhs[0]);

Data=mxGetPr(prhs[0]);

p = mxGetScalar(prhs[1]);
q = mxGetScalar(prhs[2]);

CPow.x = p;
CPow.y = q;

CCenter.x= mxGetScalar(mxGetField(prhs[3],0,"x"));
CCenter.y= mxGetScalar(mxGetField(prhs[3],0,"y"));
// CCenter.x=3;
// CCenter.y=3;

mexPrintf("C.x = %.1f C.y = %.1f\n",CCenter.x,CCenter.y);
// mexErrMsgTxt("error:");
*m = CMoment(Data,M,N,p,q,CCenter);

return ;
}

然后出现了一个很奇怪的问题,我在调用第89行代码之前查看CCenter,数据是没有问题的,但是到CMoment里面查看的时候,对应的数据就没能传递过去,为0:

我从简单入手,发现如果没有参数Data,就是说把CMoment原型和引用中的第一个参数注释掉,然后CMoment里面的和Data相关的都注释掉,此时调用前和调用后,结构体参数center都是没有问题的:

 

//%

%#/*---------------------------------------------------------------------------------------------------------------------------------------*/

 

.结构和cell array的传递

demo

#include "mex.h"
#include "string.h"

#define MAXCHARS 80


void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
const char **fnames;
const mwSize *dims;
mxArray *tmp, *fout;
char *pdata=NULL;
int ifield, nfields;
mxClassID *classIDflags;
mwIndex jstruct;
mwSize NStructElems;
mwSize ndim;


if(nrhs!=1)
mexErrMsgIdAndTxt( "MATLAB:phonebook:invalidNumInputs",
"One input required.");
else if(nlhs > 1)
mexErrMsgIdAndTxt( "MATLAB:phonebook:maxlhs",
"Too many output arguments.");
else if(!mxIsStruct(prhs[0]))
mexErrMsgIdAndTxt( "MATLAB:phonebook:inputNotStruct",
"Input must be a structure.");


nfields = mxGetNumberOfFields(prhs[0]);//获取单个结构体中的字段的个数
NStructElems = mxGetNumberOfElements(prhs[0]);//获取结构体数组中的结构体的个数

classIDflags = mxCalloc(nfields, sizeof(mxClassID));


for(ifield=0; ifield<nfields; ifield++) {
for(jstruct = 0; jstruct < NStructElems; jstruct++) {
tmp = mxGetFieldByNumber(prhs[0], jstruct, ifield);
if(tmp == NULL) {
mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
mexErrMsgIdAndTxt( "MATLAB:phonebook:fieldEmpty",
"Above field is empty!");
}
if(jstruct==0) {
if( (!mxIsChar(tmp) && !mxIsNumeric(tmp)) || mxIsSparse(tmp)) {
mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
mexErrMsgIdAndTxt( "MATLAB:phonebook:invalidField",
"Above field must have either string or numeric non-sparse data.");
}
classIDflags[ifield]=mxGetClassID(tmp);
} else {
if (mxGetClassID(tmp) != classIDflags[ifield]) {
mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
mexErrMsgIdAndTxt( "MATLAB:phonebook:invalidFieldType",
"Inconsistent data type in above field!");
} else if(!mxIsChar(tmp) &&
((mxIsComplex(tmp) || mxGetNumberOfElements(tmp)!=1))){
mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
mexErrMsgIdAndTxt( "MATLAB:phonebook:fieldNotRealScalar",
"Numeric data in above field must be scalar and noncomplex!");
}
}
}
}


fnames = mxCalloc(nfields, sizeof(*fnames));

for (ifield=0; ifield< nfields; ifield++){
fnames[ifield] = mxGetFieldNameByNumber(prhs[0],ifield);//获取单个结构体的字段的名字
}

plhs[0] = mxCreateStructMatrix(1, 1, nfields, fnames);//创建Struct的矩阵n*m维,nfields为Struct的字段数,fnames为字段名字的列表
mxFree((void *)fnames);
ndim = mxGetNumberOfDimensions(prhs[0]);//获取struct的维数
dims = mxGetDimensions(prhs[0]);//我的理解是:获取第一维的数据地址
for(ifield=0; ifield<nfields; ifield++) {

if(classIDflags[ifield] == mxCHAR_CLASS) {
fout = mxCreateCellArray(ndim, dims);//创建cell
}else {
fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxREAL);//创建数字array
pdata = mxGetData(fout);
}

for (jstruct=0; jstruct<NStructElems; jstruct++) {
tmp = mxGetFieldByNumber(prhs[0],jstruct,ifield);
if( mxIsChar(tmp)) {
mxSetCell(fout, jstruct, mxDuplicateArray(tmp));//向cell里赋值
}else {
mwSize sizebuf;
sizebuf = mxGetElementSize(tmp);
memcpy(pdata, mxGetData(tmp), sizebuf);
pdata += sizebuf;
}
}

mxSetFieldByNumber(plhs[0], 0, ifield, fout);//向结构体赋值
}
mxFree(classIDflags);
return;
}