2012-07-17 92 views
3

我想在使用S函数构建器的Simulink中创建一个s函数,它将接受一个2d数组作为输入。在输入端口中,我指定了维度:2d,rows:4,columns:4.当我尝试使用f [x] [y]访问输入端口时,它给出错误:“error C2109:subscript requires array or pointer键入“,用于输入端口所在的行。如何在输入端口为2d数组的Simulink中创建s函数?

如何在输入端口为2d数组的情况下在Simulink中创建s函数?

相关的代码:

static void mdlInitializeSizes(SimStruct *S) 
{ 
    DECL_AND_INIT_DIMSINFO(inputDimsInfo); 
    DECL_AND_INIT_DIMSINFO(outputDimsInfo); 
    ssSetNumSFcnParams(S, NPARAMS); 
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { 
    return; /* Parameter mismatch will be reported by Simulink */ 
    } 

    ssSetNumContStates(S, NUM_CONT_STATES); 
    ssSetNumDiscStates(S, NUM_DISC_STATES); 

    if (!ssSetNumInputPorts(S, NUM_INPUTS)) return; 
    /*Input Port 0 */ 
    inputDimsInfo.width = INPUT_0_WIDTH; 
    ssSetInputPortDimensionInfo(S, 0, &inputDimsInfo); 
    ssSetInputPortMatrixDimensions(S ,0, INPUT_0_WIDTH, INPUT_DIMS_0_COL); 
    ssSetInputPortFrameData(S, 0, IN_0_FRAME_BASED); 
    ssSetInputPortDataType(S, 0, SS_DOUBLE); 
    ssSetInputPortComplexSignal(S, 0, INPUT_0_COMPLEX); 
    ssSetInputPortDirectFeedThrough(S, 0, INPUT_0_FEEDTHROUGH); 
    ssSetInputPortRequiredContiguous(S, 0, 1); /*direct input signal access*/ 

    if (!ssSetNumOutputPorts(S, NUM_OUTPUTS)) return; 

    ssSetNumSampleTimes(S, 1); 
    ssSetNumRWork(S, 0); 
    ssSetNumIWork(S, 0); 
    ssSetNumPWork(S, 0); 
    ssSetNumModes(S, 0); 
    ssSetNumNonsampledZCs(S, 0); 

    /* Take care when specifying exception free code – see sfuntmpl_doc.c */ 
    ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | 
    SS_OPTION_USE_TLC_WITH_ACCELERATOR | 
    SS_OPTION_WORKS_WITH_CODE_REUSE)); 
} 

mdlOuputs我尝试治疗f(端口),为正常阵列。 例如:

x=f[0][0]; 

这会引发错误。

编辑: 那么,有点想通了。

根据输入参数设置端口尺寸,然后您可以使用f [x * xw + y]来解决这些值,其中x和y是x和y位置(从0开始),xw是列数。

还没有找到更好的方法,但这个工程。

+0

您可以复制粘贴由S-Function Builder中的'mdlInitializeSizes','mdlSetInputPortDimensionInfo'&'mdlOutputs'(你所访问的部分生成的代码港口)? – Praetorian 2012-07-17 15:37:23

+0

Stackoverflow不会让我发布在这里,所以这里是mdlInitializeSizes:http://textsave.de/?p=128363。没有mdlSetInputPortDimensionInfo。在mdlOuputs中,我尝试将f(端口)视为普通数组。例如:x = f [0] [0]。这给出了一个错误。 – 2012-07-17 16:09:42

回答

1

我猜的S-功能生成器生成代码,看起来像在mdlOutputs如下:

real_T *y0 = (real_T *)ssGetOutputPortSignal(S, 0); 
// OR 
real_T *y0 = ssGetOutputPortRealSignal(S, 0); 

无论使用哪种线y0是一个指向一个1-d阵列,所以当你尝试编译器会抱怨,使用2个下标来访问它,就好像它是一个2-D数组一样。

您可以通过将编辑中发布的二维索引更改为线性索引来解决此问题。这工作得很好,事实上,当你使用2个下标索引到2-D数组时,编译器无论如何不得不在后台执行该操作。

另一种选择是将返回值ssGetInputPortSignal(或ssGetInputPortRealSignal)投射到指针类型的指针

real_T **y0 = (real_T **)ssGetOutputPortSignal(S, 0); 

y0[1][1] = 0; 
0

正如您在编辑中提到的那样,使用线性索引实际上是访问C MEX s函数中矩阵的正确方法。看看sfun_matadd.c s函数示例中的mdlOutputs:http://www.ligo.caltech.edu/~rana/mat/Jenne/sfun_matadd.c。在该示例代码中的注释说明了它很整齐:

/* 
* Note1: Matrix signals are stored in column major order. 
* Note2: Access each matrix element by one index not two indices. 
*  For example, if the output signal is a [2x2] matrix signal, 
*  -   - 
*  | y[0] y[2] | 
*  | y[1] y[3] | 
*  -   - 
*  Output elements are stored as follows: 
*   y[0] --> row = 0, col = 0 
*   y[1] --> row = 1, col = 0 
*   y[2] --> row = 0, col = 1 
*   y[3] --> row = 1, col = 1 
*/