Simulink moves class object memory between C-MEX S-Function mdlStart() and mdlOutputs()?

1 回表示 (過去 30 日間)
Jonathan Currie
Jonathan Currie 2013 年 8 月 25 日
I have a problem where Simulink/Matlab appears to be moving the memory location of a class object between mdlStart() and mdlOuputs() within a C-MEX S Function. I am using mxGetProperty in C, however the pointer returned does not always return my data.
For example:
myclass.prop = [0 1 2];
The way I access this in a C S-Function is as follows (assuming it is the first parameter):
data = mxGetPr(mxGetProperty(ssGetSFcnParam(S, 0),0,"prop"));
Now I expect that the pointer *data should always point to the location of the values within this class object. In mdlStart() where the above line is implemented I can read 0 1 2 correctly. However reading the same pointer (declared globally) from mdlOutputs() all I get is zeros. Using a debugger and looking at the memory location, Matlab.exe is writing over this memory location (which I suspect is during moving this data elsewhere). Typical testing output:
MDLSTART
d[0] 0.000000
d[1] 1.000000
d[2] 2.000000
MDLOUT
d[0] 0.000000
d[1] 0.000000
d[2] 0.000000
Can anyone help me out on this one? It doesn't show in the documentation for mxGetProperty that it is not compatible with S Functions. And as I have 30+ properties and sub-fields to access, I do not want to have to find the pointers every time mdlOutputs() is called!
Test Class Code:
classdef testclass
properties
prop
end
end
>> myclass = testclass(); myclass.prop = [0 1 2];
Test C S-Function (save as testsfun.c)
#define S_FUNCTION_NAME testsfun
#define S_FUNCTION_LEVEL 2
#include <simstruc.h>
double * data; //global pointer
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 1);
ssSetSFcnParamTunable( S, 0, 0 );
ssSetNumContStates(S, 0); ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 0)) return;
if (!ssSetNumOutputPorts(S, 0)) return;
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0); ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0); ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);
ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
ssSetOptions(S, 0);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, 1);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
}
#define MDL_START
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
data = mxGetPr(mxGetProperty(ssGetSFcnParam(S, 0),0,"prop"));
ssPrintf("MDLSTART\nd[0] %f\nd[1] %f\nd[2] %f\n",data[0],data[1],data[2]);
}
#endif
static void mdlOutputs(SimStruct *S, int tid)
{
ssPrintf("MDLOUT\nd[0] %f\nd[1] %f\nd[2] %f\n",data[0],data[1],data[2]);
}
static void mdlTerminate(SimStruct *S)
{
}
#include "simulink.c"
"myclass" is then simply added as the parameter to a Simulink S-Function block which calls testsfun. Problem above is on R2012b 32bit on Win 7 compiled with VS2010.
  1 件のコメント
Kaustubha Govind
Kaustubha Govind 2013 年 8 月 26 日
What about if you create a workspace variable (say p) which holds an instance to "myclass" and enter 'p' as the value of the dialog parameter?

サインインしてコメントする。

回答 (0 件)

製品

Community Treasure Hunt

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

Start Hunting!

Translated by