Обмен данными между несколькими s-функциями c mex - PullRequest
0 голосов
/ 05 ноября 2018

Я реализую несколько функций c s Они должны полагаться на одни и те же указатели и переменные, не зависящие от текущей s-функции.

По сути, я хочу создать все переменные и указатели в одной s-функции «setup» (внутри mdlInitialize), а затем иметь возможность использовать эти переменные и указатели на разные s-функции в их функции mdlOutputs. Каждая s-функция будет записана в c.

Я не смог найти ни одной полезной подсказки в справке по математике. Есть ли у вас какие-либо идеи? Спасибо.

1 Ответ

0 голосов
/ 05 ноября 2018

Есть несколько способов сделать это, хотя ни один из них не является подходом лучший .

Один из подходов состоит в том, чтобы определить все в dll и загрузить его каждой из S-функций. Это изложено в вопросе Как разделить структуру C среди функций C S? .

Другой (и мой предпочтительный) подход заключается в создании пользовательского типа данных, который представляет собой C-структуру, содержащую все общие данные и передаваемую в качестве сигнала между S-функциями в модели. Это описано в разделе Using Opaque Data Types in C S-Functions документа Настройка пользовательских типов данных .

В документе показаны различные (относительно простые) вещи, которые необходимо выполнить в S-функции, которая создает пользовательскую структуру. В этом методе S-функций MdlOutputs пользовательская структура будет просто выводиться из блока обычным способом. Например, если пользовательская структура, содержащая ваши данные, определена как

typedef struct{
    real_T sig0;
    real_T sig1;
}myStruct;

Тогда в mdlInitializeSizes вам нужно что-то вроде

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';

Затем в mdlInitializeSizes любой 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 Coder).

...