MATLAB mex例程未返回正确的值

MATLAB mex routine does not return correct value

本文关键字:返回 mex 例程 MATLAB      更新时间:2023-10-16

我正在尝试构建一个供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中返回指针?

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文档警告您不要使用后者。

在MATLAB应用程序中使用mxMalloc而不是ANSI C malloc函数来分配内存。