Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Passing Pointers in Simulink

673 views
Skip to first unread message

Matthew

unread,
Sep 28, 2009, 7:14:02 AM9/28/09
to
Can I create a class in an C++ S-Function and use a pin as a pointer to the class such that in another C++ S-Function I can use that pointer address to access the class (and member functions). It seems like it should work but I was told by one of my co-workers that one of the Simulink Tech Support engineers told them not to pass pointers in Simulink. Can it be done, if so what are the gotcha's

Matthew

unread,
Sep 28, 2009, 2:49:03 PM9/28/09
to
"Matthew " <mjre...@gmail.com> wrote in message <h9q5pq$7vi$1...@fred.mathworks.com>...

> Can I create a class in an C++ S-Function and use a pin as a pointer to the class such that in another C++ S-Function I can use that pointer address to access the class (and member functions). It seems like it should work but I was told by one of my co-workers that one of the Simulink Tech Support engineers told them not to pass pointers in Simulink. Can it be done, if so what are the gotcha's

More info on What I am trying to do: (This S-Function Creates a Data Class in mdlStart and Passes it to mdlOutputs)

static void mdlOutputs(SimStruct *S, int_T tid)
{
#ifndef MATLAB_MEX_FILE
uint32_T *p_DXCallBack = (uint32_T *) ssGetOutputPortRealSignal(S,0);

DX2004_DDC *DX =(DX2004_DDC *) ssGetPWork(S)[0]; //Re-Create DX from P-Work Variable

p_DXCallBack = (uint32_T *) DX;
printf("DX Knows:%x %x %x ",DX, DX->IOAddress[0], p_DXCallBack);

#endif
}

The goal is to put a pointer to the class out on p_DXCallBack Output Pin

In a different S-Function I want to take this on an input pin and use the Class data and Functions. See Below.

static void mdlOutputs(SimStruct *S, int_T tid)
{

uint32_T *p_DXCallBack = (uint32_T *) ssGetInputPortSignal(S,0);
// void *p_DXCallBack = (void *) ssGetInputPortSignal(S,0);

if (p_DXCallBack != NULL)
{
DX2004_DDC *DX = (DX2004_DDC *) p_DXCallBack;
printf("Wants %x %x %x\n", DX, p_DXCallBack, DX->IOAddress[0]);
}
else
{
printf("NULL \n");
}
}

However somewhere in here there is a problem as the data that i set in the first S-Function is not coming across correctly into the second S-Function. Any suggestions?

Phil Goddard

unread,
Sep 28, 2009, 5:05:03 PM9/28/09
to
The following link gives an example of what you're trying to do:

http://www.tim.cz/en/nfaq/matlab-simulink/pointer-transfer.php

Phil.

Matthew

unread,
Sep 29, 2009, 11:07:02 AM9/29/09
to
"Phil Goddard" <philN...@goddardconsulting.ca> wrote in message <h9r8dv$rv0$1...@fred.mathworks.com>...

> The following link gives an example of what you're trying to do:
>
> http://www.tim.cz/en/nfaq/matlab-simulink/pointer-transfer.php
>
> Phil.

You get a GOLD STAR Phil, this worked out. To test it out quickly I wan't able to use the datatypes with RTW so I went without that extra safety check but it fired up and is working.

Here is what I did,

This is the S-Function that created the pointer: (my class is DX2004_DDC) The syntax was a little off from what we tried the last few days but this works.

#include "DX2004_DDC.h"

static void mdlInitializeSizes(SimStruct *S)
{
if (!ssSetNumOutputPorts(S, 1)) return;
/* Output Port 0 */
ssSetOutputPortWidth(S, 0, 1); //Pointer Output Pin - Nothing else needed
ssSetNumPWork(S, 1); // Memory Space for Pointer to DX Class
}

static void mdlStart(SimStruct *S)
{
DX2004_DDC *DX = new DX2004_DDC; //Create Instance of DX2004
ssGetPWork(S)[0] = (void *) DX;
}

static void mdlOutputs(SimStruct *S, int_T tid)
{

DX2004_DDC *DX =(DX2004_DDC *) ssGetPWork(S)[0]; //Re-Create DX from P-Work Variable

real_T *p_DXCallBack = ssGetOutputPortRealSignal(S,0);
p_DXCallBack[0] = (long int) DX;
DX->IOAddress[0] = 35; //Populate to see if it works
}

static void mdlTerminate(SimStruct *S)
{


DX2004_DDC *DX =(DX2004_DDC *) ssGetPWork(S)[0]; //Re-Create DX from P-Work Variable

delete DX;
}

This is a S-Function that uses the pointer:
#include "DX2004_DDC.h"
if (!ssSetNumInputPorts(S, 1)) return;
/* Input Port 0 */
ssSetInputPortWidth(S, 0, 1); //Pointer Pin - Nothing else needed for this pin
ssSetNumPWork(S, 1); // Memory Space for Pointer to DX Class

// Block update
#define MDL_UPDATE
static void mdlUpdate(SimStruct* S, int_T tid)
{
// convert double from input to pointer
InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S,0);
DX2004_DDC *DX = (DX2004_DDC*)((long int)(*u[0]));
ssGetPWork(S)[0] = (void *)DX;
}

static void mdlOutputs(SimStruct *S, int_T tid)
{

DX2004_DDC *DX = (DX2004_DDC *) ssGetPWork(S)[0];
if (DX == 0)
printf("Fail");
else
printf("Wants %d \n", DX->IOAddress[0]); //Prints 35 to the screen
}

0 new messages