简体   繁体   English

在mex中调用memcpy函数

[英]memcpy function calling inside mex

I have an interesting problem. 我有一个有趣的问题。 Namely like that; 就是这样; I am trying to use std::memcpy function inside by mex function and calling that mex function inside MATLAB like that; 我试图在mex函数中使用std :: memcpy函数,并在MATLAB中调用那个mex函数;

I2 = b_filter(I);

When I copy the whole image, it works well; 当我复制整个图像时,效果很好;

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]));

But when I try to copy some part of image 但是当我试图复制图像的某些部分时

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

it doesn't give right image part but gives unmeaningful pixel values. 它没有给出正确的图像部分,但却给出了无意义的像素值。

So what is going on here? 那么这里发生了什么?

Ha Ha! 哈哈! You've been caught by one of the nastiest of mex file nuances! 你被一个最糟糕的mex文件细微差别抓住了! It's got me before too. 它之前也有我。 Arrays in mex functions are stored in column order not row order, so you: mex函数中的数组按列顺序而不是行顺序存储,因此您:

You still use column-first indexing like in Matlab, though 不过,您仍然可以像在Matlab中一样使用列优先索引

Blog URL 博客网址

Try this page too for a nice picture of the ordering. 尝试这个页面也可以获得一个很好的订购图片。

图来自Mathworks

Finally I would recommend reading this thread to get a better idea behind the difference of C and MATLAB matrix memory being column-ordered. 最后,我建议阅读这个帖子 ,以便更好地了解C和MATLAB矩阵存储器的差异,这些差异是按列排序的。

As explained by @macduff, MATLAB uses a column-major order to store arrays, while C arrays are row-major. 正如@macduff所解释的,MATLAB使用列主要顺序来存储数组,而C数组是行主要的。

Here is a sample implementation showing how to copy part of a matrix. 这是一个示例实现,展示了如何复制矩阵的一部分。

matrix_slice_mex.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];
        }
    }
}

And to test this: 并测试这个:

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

You could have also used memcpy to copy each of the columns (one for-loop instead) 您也可以使用memcpy复制每个列(一个用于循环)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM