2

I'm writing a c++ code that opens Matlab API engine. In the demo file Matlab_ROOT/extern/examples/eng_mat/engdemo.cpp, it shows how to copy a simple 1d c style array to a mxArray:

mxArray *T = NULL; double time[10] = {};
T = mxCreateDoubleMatrix( 1,10,mxREAL);
memcpy((void*)mxGetPr(T), (void*)time, sizeof(time));

I can understand this code; so a 1d mxArray object stores the elements linearly.

However, suppose I have a 2d (or more) c array and mxArray of same size:

double time[3][5]; 
mxArray *T; 
T = mxCreateDoubleMatrix(3,5,mxREAL);

and I want to copy the elements of the c array time into mxArray T. How can I do this? I suppose if I use memcpy, it would depend on the sequence of element storage in mxArray objects. Thanks!

2 Answers 2

3

No matter what the dimensionality of your mxArray matlab always stores it as a continuous chunk in memory (column first order). That is, if your matrix M is 2-by-3

M = [ 11, 12, 13;
      21, 22, 23 ];

In memory, Matlab stores it as

[11, 21, 12, 22, 13, 23]

(The same order you'll get if you do M(:)).

Therefore, to convert a double[3][5] to mxArray you'll have to issue several memcpy commands:

double* ptr = mxGetPr( T );
for ( int i=0; i<3; i++ )
    memcpy( (void*)(ptr+i*5), (void*)time[i], 5*sizeof(double) );
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks I just realise Matlab and c stores 2d array in different order, and these are termed as 'column major' and 'row major'. I can also only issue one memcpy command to throw the c array into mxArray as it is, and do a transpose on the Matlab array later.
but the initialisation would be mxCreateDoubleMatrix(5,3,mxREAL) instead of putting (3,5)
2

One way of doing this is illustrated in another Matlab demo file matlabroot/extern/examples/refbook/arrayFillSetData.c. Things works well except that the c style array has to be in a Matlab-supported type and in linear form. Matlab stores 2d array in column major and c in row major, so care must be taken. A transpose action might be needed.

#define ROWS 2
#define COLUMNS 2
#define ELEMENTS 4

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
UINT16_T *dynamicData;                        /* pointer to dynamic data */
const UINT16_T data[] = {2, 3, 2, 1};  /* existing data */
mwSize index;

/* Check for proper number of arguments. */
if ( nrhs != 0 ) {
    mexErrMsgIdAndTxt("MATLAB:arrayFillSetData:rhs",
            "This function takes no input arguments.");
} 

/* Create a local array and load data */
dynamicData = mxCalloc(ELEMENTS, sizeof(UINT16_T));
for ( index = 0; index < ELEMENTS; index++ ) {
    dynamicData[index] = data[index];
}

/* Create a 0-by-0 mxArray; you will allocate the memory dynamically */
plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT16_CLASS, mxREAL);

/* Point mxArray to dynamicData */
mxSetData(plhs[0], dynamicData);
mxSetM(plhs[0], ROWS);
mxSetN(plhs[0], COLUMNS);

/* Do not call mxFree(dynamicData) because plhs[0] points to dynamicData */

return;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.