在mex中调用memcpy函数

时间:2013-06-14 17:15:50

标签: c++ matlab mex memcpy matrix-indexing

我有一个有趣的问题。就是这样;我试图在mex函数中使用std :: memcpy函数,并在MATLAB中调用那个mex函数;

I2 = b_filter(I);

当我复制整个图像时,效果很好;

plhs[0] =  mxCreateDoubleMatrix(mxGetM(plhs[0]), mxGetN(plhs[0]), mxREAL);          
memcpy(mxGetPr(plhs[0]), mxGetPr(prhs[0]), sizeof(double) *mxGetM(plhs[0]) * mxGetN(plhs[0]));

但是当我尝试复制图像的某些部分时

plhs[0] =  mxCreateDoubleMatrix(100, 100, mxREAL);              
memcpy(mxGetPr(plhs[0]), mxGetPr(prhs[0]), sizeof(double) * 100 * 100);

它没有给出正确的图像部分,但给出了无意义的像素值。

那么这里发生了什么?

2 个答案:

答案 0 :(得分:5)

哈哈!你被一个最糟糕的mex文件细微差别抓住了!它之前也有我。 mex函数中的数组按列顺序而不是行顺序存储,因此您:

  

尽管

,你仍然像Matlab一样使用列优先索引

Blog URL

尝试这个page以获得有关排序的精彩图片。

Figure From Mathworks

最后,我建议阅读this thread,以便更好地了解C和MATLAB矩阵存储器的差异是否为列顺序。

答案 1 :(得分:3)

正如@macduff解释的那样,MATLAB使用column-major order来存储数组,而C数组是行主要的。

以下是一个示例实现,展示了如何复制矩阵的一部分。

matrix_slice_mex.c

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *in, *out;
    mwIndex i,j;
    mwSize numRows;

    /* input checks */
    if (nrhs != 1 || nlhs > 1) {
        mexErrMsgIdAndTxt("MATLAB:nargchk", "Wrong number of arguments.");
    }
    if (mxGetNumberOfDimensions(prhs[0])>2 || !mxIsDouble(prhs[0])) {
        mexErrMsgIdAndTxt("MATLAB:wrongDims", "Expecting 2D double matrix.");
    }
    if (mxGetM(prhs[0])<100 || mxGetN(prhs[0])<100) {
        mexErrMsgIdAndTxt("MATLAB:wrongDims", "Matrix size must be >= 100x100.");
    }

    /* extract sub-matrix */
    plhs[0] = mxCreateDoubleMatrix(100, 100, mxREAL);
    out = mxGetPr(plhs[0]);
    in = mxGetPr(prhs[0]);
    numRows = mxGetM(prhs[0]);
    for(j=0; j<100; j++) {
        for(i=0; i<100; i++) {
            *out++ = in[i + numRows*j];
        }
    }
}

并测试一下:

x = rand(1000);
y = x(1:100,1:100);
yy = matrix_slice_mex(x);
isequal(y,yy)

您也可以使用memcpy复制每个列(一个用于循环)