在多个c mex s函数之间共享数据

在多个c mex s函数之间共享数据,c,simulink,mex,s-function,C,Simulink,Mex,S Function,我正在实现几个c-s函数。它们必须依赖于相同的指针和变量,不依赖于当前的s函数 基本上,我希望在一个“setup”s函数(在mdlInitialize内部)中实例化所有变量和指针,然后能够在其mdlOutputs函数中使用这些变量和不同s函数中的指针。每个s函数都将用c语言编写 我在mathworks帮助中找不到任何有用的提示。你知道吗?谢谢。有几种方法可以做到这一点,尽管它们都不是最好的方法 一种方法是在dll中定义所有内容,并由每个S函数加载。问题中概述了这一点 另一种(也是我首选的)方法是

我正在实现几个c-s函数。它们必须依赖于相同的指针和变量,不依赖于当前的s函数

基本上,我希望在一个“setup”s函数(在mdlInitialize内部)中实例化所有变量和指针,然后能够在其mdlOutputs函数中使用这些变量和不同s函数中的指针。每个s函数都将用c语言编写


我在mathworks帮助中找不到任何有用的提示。你知道吗?谢谢。

有几种方法可以做到这一点,尽管它们都不是最好的方法

一种方法是在dll中定义所有内容,并由每个S函数加载。问题中概述了这一点

另一种(也是我首选的)方法是创建自定义数据类型,它是一个包含所有共享数据的C结构,并在模型中的S函数之间作为信号传递。这在文档的“使用CS函数中的不透明数据类型”一节中进行了概述

文档显示了在创建自定义结构的S函数中需要完成的各种(相对简单的)事情。在这个S-Functions
MdlOutputs
方法中,自定义结构将以通常的方式作为块的输出。例如,如果包含数据的自定义结构定义为

typedef struct{
    real_T sig0;
    real_T sig1;
}myStruct;
然后在
mdlinializeSizes
中,您需要

myStruct tmp;

/* Register the user-defined data types */
id = ssRegisterDataType(S, "customDataType");
if(id == INVALID_DTYPE_ID) return;

/* Set the size of the user-defined data type */
status = ssSetDataTypeSize(S, id, sizeof(tmp));
if(status == 0) return;

/* Set the zero representation */
tmp.sig0 = 0;
tmp.sig1 = 0;
status = ssSetDataTypeZero(S, id, &tmp);
要将其作为信号输出,在
mdlOutputs
方法中

myStruct *pY0 = (myStruct *)ssGetOutputPortSignal(S, 0);

pY0[0].sig0 = 'value of this param';
pY0[0].sig1 = 'value of this param';
然后在需要使用此信号的任何S函数的

DTypeId  id;
id = ssRegisterDataType(S, "customDataType");
if(id == INVALID_DTYPE_ID) return;
这样,您就可以使用

myStruct **uPtrs = (myStruct **) ssGetInputPortSignalPtrs(S,0);
然后以通常的方式访问结构的元素

firstVar = uPtrs[0]->sig0;
secondVar = uPtrs[0]->sig1;

这种方法的主要缺点是模型不能用于代码生成(使用Simulink编码器)。

有几种方法可以做到这一点,尽管它们都不是最好的方法

一种方法是在dll中定义所有内容,并由每个S函数加载。问题中概述了这一点

另一种(也是我首选的)方法是创建自定义数据类型,它是一个包含所有共享数据的C结构,并在模型中的S函数之间作为信号传递。这在文档的“使用CS函数中的不透明数据类型”一节中进行了概述

文档显示了在创建自定义结构的S函数中需要完成的各种(相对简单的)事情。在这个S-Functions
MdlOutputs
方法中,自定义结构将以通常的方式作为块的输出。例如,如果包含数据的自定义结构定义为

typedef struct{
    real_T sig0;
    real_T sig1;
}myStruct;
然后在
mdlinializeSizes
中,您需要

myStruct tmp;

/* Register the user-defined data types */
id = ssRegisterDataType(S, "customDataType");
if(id == INVALID_DTYPE_ID) return;

/* Set the size of the user-defined data type */
status = ssSetDataTypeSize(S, id, sizeof(tmp));
if(status == 0) return;

/* Set the zero representation */
tmp.sig0 = 0;
tmp.sig1 = 0;
status = ssSetDataTypeZero(S, id, &tmp);
要将其作为信号输出,在
mdlOutputs
方法中

myStruct *pY0 = (myStruct *)ssGetOutputPortSignal(S, 0);

pY0[0].sig0 = 'value of this param';
pY0[0].sig1 = 'value of this param';
然后在需要使用此信号的任何S函数的

DTypeId  id;
id = ssRegisterDataType(S, "customDataType");
if(id == INVALID_DTYPE_ID) return;
这样,您就可以使用

myStruct **uPtrs = (myStruct **) ssGetInputPortSignalPtrs(S,0);
然后以通常的方式访问结构的元素

firstVar = uPtrs[0]->sig0;
secondVar = uPtrs[0]->sig1;

这种方法的主要缺点是无法在代码生成中使用模型(使用Simulink编码器)。

在生成的代码中,在S函数之间共享数据的最简单方法是通过全局变量传递数据,以防S函数是非内联的

因为您在已经定义的变量中遇到错误,所以我假设您正在目标平台中编译生成的代码。在这种情况下,它是由重复的定义引起的——全局变量必须仅在“setup”S函数中定义,并在所有其他S函数中用extern关键字声明(在目标函数中这只是一个普通的C)

在Simulink环境中使用mex编译S函数时,它不能静态链接到其他S函数。虽然可以使用相同的外部C源文件链接多个S函数,但在Simulink中,可能会获得为每个S函数独立创建的相同数据的多个实例。因为S函数是在Simulink环境中独立编译和链接的,所以在每个S函数中定义公共全局变量没有意义——您不能将它们外部化,因为它们不会为链接器(由mex调用)定义


在目标上链接全局变量的明显缺点是,不能使用Simulink环境调试依赖于共享数据的功能。但如果它不是主要功能(例如一些补充日志记录),它可以有条件地包含在S函数中的RT标志中,以仅出现在生成的代码中,从而允许验证Simulink中的主要功能。

在生成的代码中,S函数之间共享数据的最简单方法就是通过全局变量传递数据,以防S函数是非内联的

因为您在已经定义的变量中遇到错误,所以我假设您正在目标平台中编译生成的代码。在这种情况下,它是由重复的定义引起的——全局变量必须仅在“setup”S函数中定义,并在所有其他S函数中用extern关键字声明(在目标函数中这只是一个普通的C)

在Simulink环境中使用mex编译S函数时,它不能静态链接到其他S函数。虽然可以使用相同的外部C源文件链接多个S函数,但在Simulink中,可能会获得为每个S函数独立创建的相同数据的多个实例。因为S函数是在Simulink环境中独立编译和链接的,所以在每个S函数中定义公共全局变量没有意义——您不能将它们外部化,因为它们不会为链接器定义(在