Question

I got a follow up question about Matlab mex function input/output 2D array format. For example, I have a variable 'outputBuff' defined as C++ 2D integer array. After processing it, I want to output it as a 'plhs' (parameter at left hand side). Not sure how to do this.

int** outputBuff;

size_t col_outputBuff       = mxGetN(prhs[4]);
size_t row_outputBuff       = mxGetM(prhs[4]);

// Allocate the memory for 2D array
outputBuff                  = (int **)mxCalloc(col_outputBuff, sizeof(int*));

for(int x = 0; x < col_outputBuff; x++) {
    outputBuff[x] = (int *) mxCalloc(row_outputBuff, sizeof(int));
}

// Read in the data
for (int col=0; col < col_outputBuff; col++) {
    for (int row=0; row < row_outputBuff; row++) {
        outputBuff[col][row] = ((int *)mxGetPr(prhs[4]))[row+col*row_outputBuff];
    }
}

Then output it as plhs

const mwSize dims[]         = {col_outputBuff, row_outputBuff};
plhs[0]                     = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);

mxArray *outputMatrix;
outputMatrix                = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);
outputBuff[0]               = (int *)mxGetPr(outputMatrix);
outputMatrix                = (mxArray *)mxGetData(plhs[0]);

The codes can be compiled but output all zeros not as expected. Could you give me some hints? Thanks a lot. A.

Edit 1:

Hi Peter, Thanks for your reply. I do need to remain the C-style 2D matrix (or 2D array) as I defined inputBuffer as int **. Also, I have done some processing for the inputBuffer, and to simplify the problem, I didn't paste the codes for processing inputBuffer.

Something like below is not working:

int** inputBuffer;

// Codes to processing inputBuffer ... ...
// inputBuffer need to be C-Style 2D array

plhs[0]                     = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);
int** outputBuffer          = (int**)mxGetData(plhs[0]);

    for (int col=0; col < col_outputBuff; col++) {
        for (int row=0; row < row_outputBuff; row++) {
            outputBuffer[col][row]    = inputBuffer[col][row];
        }
    }

Any ideas?

Edit 2:

I have tried again as your hints:

int** outputBuff;

size_t col_outputBuff       = mxGetN(prhs[4]);
size_t row_outputBuff       = mxGetM(prhs[4]);

// Allocate the memory for 2D array
outputBuff                  = (int **)mxCalloc(col_outputBuff, sizeof(int*));

for(int x = 0; x < col_outputBuff; x++) {
    outputBuff[x] = (int *) mxCalloc(row_outputBuff, sizeof(int));
}

// Read in the data
for (int col=0; col < col_outputBuff; col++) {
    for (int row=0; row < row_outputBuff; row++) {
        outputBuff[col][row] = ((int *)mxGetPr(prhs[4]))[row+col*row_outputBuff];
    }
}

// Process the data save in outputBuff ...

// Create the output array, including memory buffers
plhs[0] = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);

// Get the pointer to the memory where you should store the data
int* outputMatrix = (int*)mxGetData(plhs[0]);

for (int col=0; col < col_outputBuff; col++) {
    for (int row=0; row < row_outputBuff; row++) {
        outputMatrix[row + col*row_outputBuff] = outputBuffer[row + col*row_outputBuff];
    }
}

However, there is compilation error that 'can't convert int* to int **'. I then try to cast

int** outputMatrix = (int**)mxGetData(plhs[0]);

Get compiled but the results are all zeros without luck. Could you have a check please? Thanks.

Was it helpful?

Solution

I got the answer with the help from Peter. I put it here for others' reference.

// Output the results 
plhs[0]                     = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);
int* outputMatrix           = (int *)mxGetData(plhs[0]);

// Read in the data
for (int col=0; col < col_outputBuff; col++) {
    for (int row=0; row < row_outputBuff; row++) {
        outputMatrix[row + col*row_outputBuff] = outputBuff[col][row];
    }
}

OTHER TIPS

The problem with your code is that you aren't clearly understanding what assignment does to variables. If you assign outputMatrix = mxCreate...(), then in two lines outputMatrix = somethingelse, then you've overwritten the value. Assignment in C takes the value on the right and stores into the variable on the left.

Actually the whole thing is much simpler:

// Create the output array, including memory buffers
plhs[0] = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);
// Get the pointer to the memory where you should store the data
int* outputBuffer = (int*)mxGetData(plhs[0]);
int* inputBuffer  = (int*)mxGetData(prhs[4]);

for (int col=0; col < col_outputBuff; col++) {
    for (int row=0; row < row_outputBuff; row++) {
        outputBuffer[row + col*row_outputBuff] = inputBuffer[row + col*row_outputBuff];
     }
}

That's it. Notice that I'm indexing the output matrix just like the input: as a contiguous memory buffer, using multiplications.

If you have existing code that really needs the C-style 2D matrix, then convert it this way at the final step.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top