How do I store a string from a MATLAB structure into a C structure in a MEX file?
4 views (last 30 days)
Show older comments
I am building a MEX file that converts a MATLAB structure to a C structure, manipulates the C structure, and returns a modified MATLAB structure. A portion of the code that produces behavior I cannot explain is shown below. In the code portion, the variable "mx" is an mxArray structure, and the variable "cstructu" is a C structure.
field = mxGetField(mx, 0, "Field1");
ch = mxArrayToString(field);
strcpy(cstructu->Field1,ch);
mexPrintf("\n%s",cstructu->Field1);
field = mxGetField(mx, 0, "Field2");
ch = mxArrayToString(field);
strcpy(cstructu->Field2,ch);
mexPrintf("\n%s",cstructu->Field2);
field = mxGetField(mx, 0, "Field3");
ch = mxArrayToString(field);
strcpy(cstructu->Field3,ch);
mexPrintf("\n%s",cstructu->Field3);
mexPrintf("\n%s",cstructu->Field1);
mexPrintf("\n%s",cstructu->Field2);
mexPrintf("\n%s",cstructu->Field3);
The above code is divided into four code "blocks". The first three code blocks end in a "mexPrintf" statement that outputs to the command prompt the value stored for a given field in the C structure. The outputs from these three statements are as expected. The issue is with the "mexPrintf" statements in the fourth code block. When I print the value of "Field1", I get a concatenation of the values of "Field1", "Field2", and "Field3". When I print the value of "Field2", I get a concatenation of the values of "Field2" and "Field3". And when I print the value of "Field3", I just get the value of "Field3". What causes this behavior, and what do I need to do to correct it?
0 Comments
Accepted Answer
James Tursa
on 1 Nov 2021
Edited: James Tursa
on 1 Nov 2021
Please show us the definitions of the variables involved. How large is cstructu->Field1, cstructu->Field2, and cstructu->Field3? I.e., how many characters can these hold? Are these arrays or dynamically allocated? How long are the strings you are getting from mx?
If the strings you are getting from MATLAB are longer than the number of characters that cstructu->Field1 can hold, then it might be that when writing into cstructu->Field2 you are overwriting the null character of cstructu->Field1, and similarly for the other cases. I.e., it could be a simple case of writing beyond the array size. You should check this, but we can't check this because you didn't show us enough code. E.g., if the MATLAB string is 10 characters then your C struct array needs to hold at least 11 characters because you need room for the trailing null character.
As a side note, your code is leaking the memory behind ch. You should have an mxFree(ch) statement after you are done using a particular ch.
4 Comments
Walter Roberson
on 1 Nov 2021
strcpy() does not protect against overwriting when the source is too long for the destination.
I worry about the possibility that the source character vector might happen to have characters beyond U+00FF . strcpy() is really only designed for char* and not for wide characters. The documentation for mxArrayToString specifically mentions multibyte but it is not specific enough for my tastes as to how it handles multibyte.
There also https://www.mathworks.com/help/matlab/apiref/mxarraytoutf8string.html which is specific that it encodes to UTF-8 .
If you might possibly have multibyte then the required destination size is variable.
James Tursa
on 1 Nov 2021
@Joel Williams FYI this
field = mxCreateDoubleMatrix(1, 1, mxREAL);
pr = mxGetPr(field);
*pr = cstructu->Field4;
can be replaced with this
field = mxCreateDoubleScalar(cstructu->Field4);
And to make your code more robust I would suggest putting in code to check the length of the MATLAB strings before you copy them into your C struct. Throw an error if they are too long.
More Answers (0)
See Also
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!