MATLAB Answers

0

Can I create a C++ MEX-file S-function?

Is there any documentation on creating S-functions using C++ MEX-files?

1 Answer

Answer by MathWorks Support Team on 27 Jun 2009
 Accepted Answer

We officially support C++ MEX-file S-functions as of Simulink 4.0 (R12).
To view an example of how to do this, please type:
sfundemos
at the MATLAB Command Prompt. This will open sfundemos.mdl. This demo that ships with SIMULINK provides examples of how to write different types of S-Functions and includes a C++ example.
You can also take a look at chapter 4 of the "Writing S-function" manual which has a good description on writing C++ MEX-file S-functions.
When writing the S-function, declare the MEX Function as extern "C". The rest of the code that you write can all be in C++. For example:
extern "C"
{
void mexFunction(
int nlhs_,
mxArray *plhs_[],
int nrhs_,
const mxArray *prhs_[])
{
/* Body can use all C++ language features and file can be compiled with a
C++ compiler
*/
}
}
Below is the 'Timestwo' example written as a C++ file. You can compile the file using the MEX command. Note that if you are using the Watcom compiler, you need to add the -DNO_BUILT_IN_SUPPORT_FOR_BOOL flag to your COMPFLAGS option in your options file.
If you are using MSVC 5.0, you do not need to add this flag. The C compiler will automatically know to compile it as C++ code using the mex command.
/*
* TIMESTWO An example C-file S-function for multiplying an input by 2
*
* y = 2*x
*
* See sfuntmpl.c for a general S-function template.
*
* See also VSFUNC, DSFUNC, SFUNTMPL.
*
* Copyright (c) 1990-96 by MathWorks, Inc.
* All Rights Reserved
* $Revision: 1.1 $
*/
#ifdef __cplusplus
extern "C" {
#endif
#define S_FUNCTION_NAME timestwo_level1_cpp
/* The following three lines are necessary for the WATCOM compiler
* only. You need to remove these lines for the MSVC compiler.
*/
#ifndef COMPILER_SUPPORTS_BOOL
typedef int bool;
#endif
#include "simstruc.h"
/*
* mdlInitializeSizes - initialize the sizes array
*/
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumContStates( S, 0); /* number of continuous states */
ssSetNumDiscStates( S, 0); /* number of discrete states */
ssSetNumInputs( S, DYNAMICALLY_SIZED); /* number of inputs */
ssSetNumOutputs( S, DYNAMICALLY_SIZED); /* number of outputs */
ssSetDirectFeedThrough(S, 1); /* direct feedthrough flag */
ssSetNumSampleTimes( S, 1); /* number of sample times */
ssSetNumSFcnParams( S, 0); /* number of input arguments */
ssSetNumRWork( S, 0); /* number of real work vector elements */
ssSetNumIWork( S, 0); /* number of integer work vector elements */
ssSetNumPWork( S, 0); /* number of pointer work vector elements */
}
/*
* mdlInitializeSampleTimes - initialize the sample times array
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
/*
* mdlInitializeConditions - initialize the states
*/
static void mdlInitializeConditions(double *x0, SimStruct *S)
{
}
/*
* mdlOutputs - compute the outputs
*/
static void mdlOutputs(double *y, double *x, double *u, SimStruct *S, int tid)
{
class mul2 {
double *u;
double *y;
int width;
public:
mul2(double *u_i, double *y_i, int width_i)
{
u = u_i;
y = y_i;
width = width_i;
}
void output(void)
{
for (int i=0;i<width;i++)
{
*y++=2.0*(*u++);
}
}
};
class mul2 m(u,y,ssGetNumOutputs(S));
m.output();
}
/*
* mdlUpdate - perform action at major integration time step
*/
static void mdlUpdate(double *x, double *u, SimStruct *S, int tid)
{
}
/*
* mdlDerivatives - compute the derivatives
*/
static void mdlDerivatives(double *dx, double *x,
double *u, SimStruct *S, int tid)
{
}
/*
* mdlTerminate - called when the simulation is terminated.
*/
static void mdlTerminate(SimStruct *S)
{
}
#ifdefMATLAB_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
#ifdef __cplusplus
}
#endif

  0 Comments

Sign in to comment.