MEX - how to deepcopy returned data so MATLAB does not free it?

2 views (last 30 days)
I have code written in C that I successfully compiled to MEX, but I have trouble with exchanging data between the C part and MATLAB.
My C code creates a structure that I return to MATLAB, and then after some time, MATLAB returns that structure back to the C code, but the data in the structure is lost by then (I suspect MATLAB has probably freed the memory).
What I do is basically (C):
// create a "Message" structure somewhere in the C code
MessageStruct *message = calloc(1, sizeof(MessageStruct));
message->type = 1; // set some member of the struct
// create a returnable message using mxCalloc, so the original memory can be freed
MessageStruct *returnableMessage = mxCalloc(1, sizeof(MessageStruct));
// copy the content
memcpy(returnableMessage, message, sizeof(MessageStruct));
// create a structure that can be returned (in reality there are more members than just one)
const char *fieldnames[1];
fieldnames[0] = (char*)mxMalloc(20);
memcpy(fieldnames[0],"type",sizeof("type"));
plhs[0] = mxCreateStructMatrix(1,1,1,fieldnames);
mxFree( fieldnames[0] );
// create mxArray and set the field of the output
mxArray *type = mxCreateDoubleScalar(returnableMessage->type);
mxSetFieldByNumber(plhs[0],0,0, type);
// free the original message and leave freeing the returnableMessage to MATLAB
free(message);
In MATLAB I get the struct by calling the corresponding MEX function and save it in a cell array:
msg = myMexFun();
allMessages{end+1, 1} = msg; % this is where I feel I have to deepcopy the data
So far, it works. The message contains the correct data.
But then, after a while, I want to return the message back to C, but the data is gone and the struct is empty.
How could I deepcopy the data from the message to the cell array, and not only store a pointer to the original data that probably gets freed then? I want to be able to free the memory myself by deleting the element in the cell array within MATLAB.
  6 Comments
James Tursa
James Tursa on 27 Jun 2022
Edited: James Tursa on 27 Jun 2022
"The content of the field in my C-struct is int32, so I think it should be fine. Why do you think it was double?"
This code coverts returnableMessage->type into a double and stores it in the returned mxArray:
mxArray *type = mxCreateDoubleScalar(returnableMessage->type);
mxSetFieldByNumber(plhs[0],0,0, type);
Then this code seems to get the same MATLAB struct and treat this double as an int32 through pointer type punning:
mxArray *type = mxGetField(prhs[0], 0, "type");
int32_t *ctype = (int32_t*) mxGetData(type);
Hence Jan's comment. You appear to be treating a 64-bit floating point bit pattern as a 32-bit integer.
Robin Pape
Robin Pape on 28 Jun 2022
Edited: Robin Pape on 28 Jun 2022
Okay, got it. It works now, the problem was probably a combination of the incorrect data type and me forgetting one mxGetPr()...
Thank you!

Sign in to comment.

Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Tags

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!