Effacer les filtres
Effacer les filtres

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

1 vue (au cours des 30 derniers jours)
Jonathan Currie
Jonathan Currie le 25 Août 2013
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 commentaire
Kaustubha Govind
Kaustubha Govind le 26 Août 2013
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?

Connectez-vous pour commenter.

Réponses (0)

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by