How to access Matlab string() data in MEX/C?
19 ビュー (過去 30 日間)
古いコメントを表示
Hello,
I'm pretty new to Matlab, and I'm trying to write a MEX function that interfaces with a Matlab script that creates a lot of string array data. This is specifically "strings", not mxChar arrays.
However, I can't figure out how to access this string data after passing it to the MEX function. All of the relevant functions (mxGetChars, mxGetString, mxArrayToString, etc) seem to only work with mxChar arrays, and the more generic functions are unable to parse or even understand a string array object.
Are there any API calls I can use that haven't been documented yet, or will I just have to do a bunch of data manipulation before and after the MEX function call within Matlab itself? Passing everything through conversion functions like cellstr() kind of works, but seems like a lot of overhead. I also understand that using char arrays instead of strings for general use might be preferable, but I'm trying to change as little of the original Matlab code as possible.
A generic example of what I'm trying to parse:
stringarray = [string('one', string('two')];
mexTestFunction(stringarray);
1 件のコメント
Jim Hokanson
2024 年 5 月 6 日
編集済み: Jim Hokanson
2024 年 5 月 6 日
related ... (no solution given though) https://www.mathworks.com/matlabcentral/answers/2102376-how-do-i-process-a-string-class-in-a-mex-function
回答 (2 件)
John
2018 年 6 月 29 日
編集済み: John
2018 年 6 月 29 日
I'm dealing with the same issue. As a cleaner, but higher runtime cost alternative, you can make a Matlab call to convert the string to a char array. Here is an example of parsing a single Matlab string:
...
}else if( mxIsClass(pr, "string") ){
//Matlab's String class is encapsulated,
//use Matlab call to convert it to char array
mxArray *string_class[1], *char_array[1];
string_class[0] = pr;
mexCallMATLAB(1, char_array, 1, string_class, "char");
//Parse the char array to create an std::string
int buflen = mxGetN(char_array[0])*sizeof(mxChar)+1;
char* buf = new char[buflen];
mxGetString(char_array[0],buf,buflen);
data = std::string(buf);
delete buf;
}else{
...
That being said, making too many Matlab calls defeats the point of a MEX function, so I am going to look at hacking into the private string data field. Thanks for the info!
Edit: As long as Matlab's string implementation doesn't change, you can use:
}else if( mxIsClass(pr, "string") ){
mxArray* char_array = mxGetProperty(pr,0,"data");
int buflen = mxGetN(char_array)*sizeof(mxChar)+1;
char* buf = new char[buflen];
mxGetString(char_array,buf,buflen);
data = std::string(buf);
delete buf;
}else{
This will actually create a copy of the data property and the blog post Jim listed includes a workaround to directly access the property, but for small strings it's probably just as well to copy the data.
2 件のコメント
Cris Luengo
2021 年 5 月 24 日
I have been playing with this. Unfortunately, mxGetProperty doesn't work with private properties. It returns a NULL pointer. Calling back to MATLAB to convert using char or cellstr (for a string array with more than one string) is the best approach.
Antonio Javier Barragán Piña
2021 年 12 月 22 日
Thanks! You saved me! It is an undesirable solution, but under the circumstances, it is better than nothing.
James Tursa
2017 年 3 月 20 日
編集済み: James Tursa
2017 年 3 月 20 日
I don't have a recent enough version of MATLAB & C compiler to check this, but I suspect that the string class is an OOP classdef object. You can check this by passing in a string variable to the following mex routine and checking the result:
#include "mex.h"
int mxIsOpaque(const mxArray *); /* Undocumented API function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if( nrhs ) {
plhs[0] = mxCreateDoubleScalar(mxIsOpaque(prhs[0]));
}
}
If the result is a 1, then the variable is opaque (i.e., a classdef object). Unfortunately, the only way to deal with these in a mex routine is through the mxGetProperty and mxPutProperty API functions. But these will only work for you if you know the property names and are allowed to access them. And even if you can get at the top level properties of a string object, the actual data you want to get at may be buried multiple levels down deep within the object, and you might have no hope of retrieving it in a mex routine. Good luck ...
2 件のコメント
Jim Hokanson
2017 年 10 月 23 日
It seems like the format for mxIsOpaque returns a bool, not an int (for 2016b). I just commented that line out and the code works.
In terms of the result, I'm getting a 1 (is opaque).
Jim Hokanson
2017 年 10 月 24 日
String data is stored as 'data' in the string class.
mc = ?string;
mc.PropertyList
So try James' property accessor code on the 'data' property. https://undocumentedmatlab.com/blog/accessing-private-object-properties
参考
カテゴリ
Help Center および File Exchange で Cell Arrays についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!