MATLAB Answers

How to access Matlab string() data in MEX/C?

21 views (last 30 days)
Jake M
Jake M on 20 Mar 2017
Edited: John on 29 Jun 2018
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);

Answers (2)

James Tursa
James Tursa on 20 Mar 2017
Edited: James Tursa on 20 Mar 2017
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 Comments

Sign in to comment.


John
John on 29 Jun 2018
Edited: John on 29 Jun 2018
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.

Community Treasure Hunt

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

Start Hunting!