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

조회 수: 4 (최근 30일)
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?

채택된 답변

James Tursa
James Tursa 2021년 11월 1일
편집: James Tursa 2021년 11월 1일
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
Walter Roberson
Walter Roberson 2021년 11월 1일
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 2021년 11월 1일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

제품


릴리스

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by