0

I have been trying to create a C Shared Library using Matlab compiler that will be used as a plug in library to a different application for a while now. I recently thought I had completed this task only to realize that the function I was calling from my newly "Matlab Compiled" Shared Library needed to convert its return to a C structure.

I used the example found on the Matlab Answers site to help me create the wrapper level2 function to call my Matlab function which needs to return a structure.(http://www.mathworks.com/matlabcentral/answers/94715-how-do-i-wrap-matlab-compiler-4-8-r2008a-created-c-dlls-to-create-another-dll)

My issue is at the Convert returned MATLAB data to C data part of the code found below. I can convert to ints, doubles, chars, etc. fine, but I am having trouble figuring out how to code the conversion from an mxArray returned by matlab to a C structure.

/* Wrapper for level 1 function exported by the MATLAB generated DLL         *
 * This function converts C data to MATLAB data, calls the MATLAB generated  *
 * function in level1.dll and then converts the MATLAB data back into C data */

int wmlfLevel1(double* input2D, int size, char* message, double** output2d){
    int nargout=1;

    /* Pointers to MATLAB data */
    mxArray *msg;
    mxArray *in2d;
    mxArray *out2d=NULL;

    /* Start MCR, load library if not done already */
    int returnval=isMCRrunning();
    if(!returnval)
        return returnval;

    /* Convert C data to MATLAB data */
    /* IMPORTANT: this has to be done after ensuring that the MCR is running */
    msg=mxCreateString(message);
    in2d=mxCreateDoubleMatrix(size, size, mxREAL);
    memcpy(mxGetPr(in2d), input2D, size*size*sizeof(double));

    /* Call the M function */
    returnval=mlfLevel1(nargout, &out2d, in2d, msg);

    /*Convert returned  MATLAB data to C data */
    *output2d=(double *)malloc(sizeof(double)*size*size);
    memcpy(*output2d, mxGetPr(out2d), size*size*sizeof(double));

    /* Clean up MATLAB variables */
    mxDestroyArray(msg);
    mxDestroyArray(in2d);
    mxDestroyArray(out2d);

    return returnval;
}

So far I have tried using the mxCreateStructMatrix function, I tried creating a C structure skeleton, i am about to try the libstruct function, but as I am new to C Programming and the Matlab compiler any assistance would be greatly appreciated!

1 Answer 1

1

mxGetPr is simply returning a pointer to a buffer of doubles. The malloc call is allocating enough space to store size^2 doubles. memcpy is copying the data from out2d's internal storage and into your buffer.

The buffer is one-dimensional, so you'll have to compute the index based on the row and column. You can use something like output2d[col * size + row] to access a specific value. (That may be transposed - I don't have access to the docs right now.)

When you're completely done with output2d, you'll need to call free(output2d) to deallocate the memory, otherwise your code will have a memory leak.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks Katie, I have a few more questions I need clarified. Do I need to change the malloc call to allocate space according to the type struct, since that is the type I want my data to be stored in. I want my data copied from out2d into structure similar to the one below, how would this change my code? Do I need to set up a C structure first and then use memcpy to move my out2d data into it? 'struct output2d { int variable1; double vairable2; char variable3[10]; }'
Your structure will need space to store the data. If you don't know size beforehand, you'll still need to malloc it. (If you do know it, then you can declare a fixed size 2-dimensional array.) The struct should contain something like double* matrix element for your data. Then you can do output2d.matrix = malloc(sizeof(double) * size * size) and memcpy(output2d.matrix, mxGetPtr....
I used this example to show my problem, in my code I calculate a structure with 13 data fields some of them simply integers some are arrays (matrices in Matlab) and one is a string. If I defined the structure first would I then perform a output2d.element1 = malloc(sizeof(element1'stype)*size*size)), memcpy(output2d.element1,mxGetpr(out2d)... and repeat for all 13 fields?
Matlab structs are dynamic and use strings to identify fields. If you want mlfLevel1 to output to a struct, then you have to disassemble the matlab struct and re-assemble it into a C struct. I don't encourage the use of malloc in this case, try mxMalloc: mathworks.com/help/matlab/apiref/mxmalloc.html?refresh=true
@user3528438, thanks for the tip, I went ahead and substituted that where necessary and decided to just have mlfLevel1 return the data in individual variables and then assign those values to a C struct. I'm assuming that is what you meant by disassembling the Matlab structure and re-assembling it into a C struct. Either way I figured a way around my problem thanks to you so Cheers!

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.