MATLAB mex例程不返回正确的值

时间:2014-06-12 21:56:11

标签: c++ matlab mex

我正在尝试为MATLAB构建一个C / C ++函数来调用。这是我的C / C ++代码:

#include "mex.h"

double* MyarrayProduct(double* a, double* b, int N)
{
    double* c = (double*)malloc(N*sizeof(double));
    double* pc = c;

    for (int n = 0; n < N; n++)
    {
        *pc = *a**b;
        pc++;
        a++;
        b++;
    }

    return c;
}

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{

    //------------------------------------------ Verify MEX-File Input and Output Parameters -----------------------------------------------------//
    //To check for two input arguments, multiplier and inMatrix, use this code.
    if(nrhs!=2) 
    {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",
                      "Two inputs required.");
    }

    //Use this code to check for one output argument, the product outMatrix.
    if(nlhs!=1) 
    {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",
                          "One output required.");
    }

    if( !mxIsDouble(prhs[1]) || 
         mxIsComplex(prhs[1])) 
    {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble",
            "Input matrix must be type double.");
    }

    /* check that number of rows in second input argument is 1 */
    if(mxGetM(prhs[1])!=1) 
    {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",
                          "Input must be a row vector.");
    }


    //------------------------------------------ variable declarations here ----------------------------------------//
    double *inMatrixA;      /* input scalar */
    double *inMatrixB;       /* 1xN input matrix */

    int ncols;           /* size of matrix */

    double *outMatrix;      /* output matrix */


    //------------------------------------------- read in data -----------------------------------------//
    /* get the value of the scalar input  */
    inMatrixA =  mxGetPr(prhs[0]);


    /* create a pointer to the real data in the input matrix  */
    inMatrixB = mxGetPr(prhs[1]);


    /* get dimensions of the input matrix */
    ncols = mxGetN(prhs[1]);


    //------------------------------------------- Prepare Output Data -----------------------------------------//
    /* create the output matrix */
    plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);

    /* get a pointer to the real data in the output matrix */
    outMatrix = mxGetPr(plhs[0]);

    /* call the computational routine */
    outMatrix = MyarrayProduct(inMatrixA,inMatrixB,ncols);


/* code here */
}

这是我的MATLAB重播。

>> a =[1 2 3]

a =

     1     2     3

>> b = [4 5 6]

b =

     4     5     6

>> mex MyarrayProduct.cpp
>> c = MyarrayProduct(a,b)

c =

     0     0     0

我介入了我的C / C ++代码,并在

找到了
outMatrix = MyarrayProduct(inMatrixA,inMatrixB,ncols);

outMatrix实际上是4,10,18,这是正确的。但似乎很难将结果发回。我想知道这里有什么问题?我不能在mex中返回一个指针?

1 个答案:

答案 0 :(得分:0)

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

mxCreateDoubleMatrix调用上方的行上已经为您分配了一个大小为1 x ncols的矩阵。

outMatrix = MyarrayProduct(inMatrixA,inMatrixB,ncols);

你在这里所做的只是覆盖outMatrix的值,即它指向的内存位置。你实际上并没有覆盖mxCreateDoubleMatrix分配的内存。


要解决此问题,请将MyarrayProduct()功能更改为:

void MyarrayProduct(double* a, double* b, int N, double* pc)
{
    for (int n = 0; n < N; n++)
    {
        *pc = *a**b;
        pc++;
        a++;
        b++;
    }
}

然后将其称为

/* call the computational routine */
MyarrayProduct(inMatrixA,inMatrixB,ncols,outMatrix);

另一个应该有效的解决方案,同时保持MyarrayProduct()不变(主要是):

/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,0,mxREAL); // don't allocate any memory yet

/* call the computational routine */
outMatrix = MyarrayProduct(inMatrixA,inMatrixB,ncols);

/* free the existing real array (in case MATLAB allocates a size 0 array) */
mxFree(mxGetPr(plhs[0]));

/* reassign the array in the matrix */
mxSetPr(plhs[0], outMatrix);

/* set the correct dimensions */
mxSetN(plhs[0], ncols);

但是,即使在这种情况下,我也会修改MyarrayProduct(),以便它使用mxMalloc代替malloc。链接的MathWorks文档警告您不要使用后者。

  

使用mxMalloc代替ANSI C malloc函数在MATLAB应用程序中分配内存。