0

我用 C 语言编写了一个 Simulink S-Function(级别 2)。生成的模块有一个输出和一个参数。此参数存储在一个变量中,该变量在设置块之后立即在文件范围内定义:

#define NUM_PARAMS 1
#define NUM_INPORTS 0
#define NUM_OUTPORTS 1

unsigned short int MASK_INDEX;

我在 mdlInitializeSizes 中分配它,并对它的值做一些操作:

static void mdlInitializeSizes(SimStruct *S) {  
    // Check Parameters
    ssSetNumSFcnParams(S, NUM_PARAMS);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
            return;
    }

    MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));

    (...) operations
}

我的问题是,变量 MASK_INDEX 似乎是全局的,并且在相同类型的所有块之间共享。因此,它对所有块都具有相同的值。

作为一种解决方法,我每次都重新加载它,然后重新执行操作,例如:

static void mdlOutputs(SimStruct *S, int_T tid) {
    MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));

    (...) operations
}

我怎样才能得到一个真正的“局部变量”,这样我就不必每次都重复这一切?

4

1 回答 1

2

您没有提到您声明的位置MASK_INDEX,但从您的描述来看,它听起来像是在文件范围内。如果是这样,那么是的,这个变量将在所有实例之间共享。这并不以任何方式与 S-Function 隔离,它是大多数(如果不是全部)平台上的共享库的行为方式。共享库的单个实例将由应用程序加载,在本例中为 MATLAB;因此只有一个全局变量的副本。

最简单的选项是ssGetSFcnParam每次要访问参数时使用。如果您深入研究这些 S-Function 宏,它们只是在访问 的字段SimStruct,因此重复访问不太可能导致性能下降。我什至看到过使用宏来包装常见用例,例如您拥有的用例。

如果你真的想缓存对话框参数,最简单的可能是使用ssSetUserData. 声明 astruct包含一个MASK_INDEX成员(您不必使用astruct但这种方法更具可扩展性)。mxMalloc使用within动态分配实例mdlStart并将其分配给块的用户数据。确保您SS_OPTION_CALL_TERMINATE_ON_EXITssSetOptions调用中设置mdlInitializeSizes。然后定义mdlTerminate函数,您将在其中访问分配的structusingssGetUserDatamxFree它。现在您可以访问using中的struct成员。mdlOutputsssGetUserData

还有其他更高级的选项,例如工作向量,可能是PWork向量

如果您的参数是可调的,则另一个选项是使用运行时参数,它允许您缓存和可选地转换块的对话框参数。

在你的情况下,我会坚持ssGetSFcnParammdlOutputs.

于 2014-07-18T18:17:33.187 回答