How do I store a string from a MATLAB structure into a C structure in a MEX file?

4 visualizaciones (últimos 30 días)
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?

Respuesta aceptada

James Tursa
James Tursa el 1 de Nov. de 2021
Editada: James Tursa el 1 de Nov. de 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 comentarios
Walter Roberson
Walter Roberson el 1 de Nov. de 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
James Tursa el 1 de Nov. de 2021
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.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Productos


Versión

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by