S-Function String Parameter C++

14 次查看(过去 30 天)
Hey,
I've trouble reading the value of a string passed to MATLAB as an S-Function parameter in C++:
std::string str(mxArrayToString(ssGetSFcnParam(S,0)));
Throws the following exception:
Program: C:\windows\SYSTEM32\MSVCP140D.dll
File: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xstring
Line: 1181
Expression: invalid null pointer
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
MATLAB.exe has triggered a breakpoint.
Exception thrown at 0x00007FFB6C9A0A63 (test.mexw64) in MATLAB.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
> throw_segv_longjmp_seh_filter()
throw_segv_longjmp_seh_filter(): invoking THROW_SEGV_LONGJMP SEH filter
> throwSegvLongjmpFilter()
MATLAB.exe has triggered a breakpoint.
The program '[19672] MATLAB.exe' has exited with code 0 (0x0).
For debugging purposes I splitted it up:
const mxArray* pArrayValue = ssGetSFcnParam(S,0);
const char* pCharArray = mxArrayToString(pArrayValue);
std::string str(pCharArray);
pCharArray points to:
0x000000000000000
I am using VS 14.0.25431.01 Update 3 on Win 10 Pro 17134.165 with Matlab 2018a. I found code in our companies repository where both of the above code snippets are working, in MATLAB 2013b, what am I doing wrong? Is this syntax invalid in 2018a?
Edit 31.08.18:
I added an example:
#define S_FUNCTION_LEVEL 2
#define S_FUNCTION_NAME sfun_pass_string
#include "simstruc.h"
#include <string>
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 1);
ssSetSFcnParamTunable(S, 0, SS_PRM_NOT_TUNABLE);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
if (!ssSetNumInputPorts(S,1)) return;
ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetNumSampleTimes(S, 1);
ssSetOptions(S, SS_OPTION_CALL_TERMINATE_ON_EXIT);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
}
#define MDL_START
static void mdlStart(SimStruct *S)
{
mexPrintf("class of parameter: %s", mxGetClassName(ssGetSFcnParam(S,0)));
const mxArray* pArrayValue = ssGetSFcnParam(S,0);
const char* pCharArray = mxArrayToString(pArrayValue);
std::string string_1(pCharArray);
mexPrintf(string_1.c_str());
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
}
static void mdlTerminate(SimStruct *S)
{
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
  3 个评论
Nils Gerke
Nils Gerke 2018-8-30
You might be right.
mxArray test = *pArrayValue;
Gives me a compiler error:
Error C2079 'test' uses undefined struct 'mxArray_tag'
I've only one Parameter that I pass to the S-Function, in the model I write the string in double quotes.
I'm a C++ beginner, but still I really don't get whats wrong with that code. If I pass a string to the simulink model I would suspect (based on the documentation) that
ssGetSFcnParam(S,0)
gives me back my string as mxArray and that
mxArrayToString()
would convert it to a std::string. Or is this assumption wrong?
Titus Edelhofer
Titus Edelhofer 2018-8-30
Nils,
mxArray test = ...
will not work, since you always have to use pointers ...
Titus

请先登录,再进行评论。

采纳的回答

Titus Edelhofer
Titus Edelhofer 2018-8-31
Hi Nils,
I didn't take a look into the zip file but could it be that you did the same mistake as I, namely, really passing a string ("hello") to the S-function instead of the char array ('hello')? If I use the string class, then I see the same problem. When passing an old fashioned char array, then everything works as expected.
Titus
  3 个评论
Nils Gerke
Nils Gerke 2018-8-31
That did the trick, I marked your answer as accepted. But never the less I would suspect
mxArrayToString()
to be able to process string input as well as char array input. If this is not possible it would be nice to throw a proper exception. Now all that happens is that MATLAB crashes with a Fatal Exception.
Titus Edelhofer
Titus Edelhofer 2018-8-31
Yes and no: yes, the fatal exception is indeed "undesirable" :). And yes again: would be good if the function also accepts strings and not only char arrays. Now for the no: this is the C world, and it's (unfortunately?) the users responsibility to check return values.
It's the further processing of the NULL pointer that causes the exception. In the doc you see:
Returns C-style string. Returns NULL on failure. Possible reasons for failure include out of memory and specifying an array that is not an mxCHAR array.
Titus

请先登录,再进行评论。

更多回答(1 个)

Titus Edelhofer
Titus Edelhofer 2018-8-30
Hi Nils,
just to be sure: did you check the number of parameters you passed? I guess you are sure that there is at least one parameter, but may helps to check, because otherwise it looks fine. Try
int nParam = ssGetSFcnParamsCount(S);
mexPrintf("Number of parameters: %d\n", nParam);
Titus
  5 个评论
Titus Edelhofer
Titus Edelhofer 2018-8-31
O.K., then I guess we need to wait to see a reproducing example ...
Nils Gerke
Nils Gerke 2018-8-31
I added a reproducing example, see code and .zip of post 1

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 String 的更多信息

产品


版本

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by