Данные MATLAB в S-функциях C

Данные MATLAB® представлены как mxArrays на языке C/C++. Структура mxArray обычно содержит тип, размерность, данные, тип данных, разреженность и полевые и полевые количества массива MATLAB. В S-функциях Диалоговые Параметры Передачи к значениям S-функций, оцененным в MATLAB, передаются в Simulink® как mxArray. См. Матричный API C (MATLAB) для списка функций.

S-функции считывают данные MATLAB в основном в следующих целях:

  • Диалоговые параметры блока Access с помощью mxArrays

  • Передайте аргументы или от функции MATLAB с помощью mexCallMATLAB

манипуляция с массивами MX

Можно управлять mxArrays в S-функциях с помощью стандартных функций MATLAB API. В целом, если ваша S-функция является объявленной исключительной ситуацией, свободной путем передачи опции SS_OPTION_EXCEPTION_FREE_CODE ssSetOptions (см. Исключение, Свободный Код в Обрабатывает Ошибки в S-функциях), это должно избежать функций MATLAB API, которые выдают исключения (т.е. прыжок в длину), такой как mxCreateDoubleMatrix. В противном случае S-функция может использовать любую из перечисленных функций.

Примечание

S-параметры-функции только для чтения в рамках алгоритма S-функции. Можно изменить значения параметров через диалоговое окно Блока s-function или маску.

Если у вас есть Simulink Coder™, он поддерживает подмножество функций манипуляции с mxArray, когда генерация не встроила код для S-функции. Для списка поддерживаемых функций смотрите Запись Невстроенная S-функция (Simulink Coder).

Вызовы макро-ssGetSFcnParam возвращают указатель на mxArray, который может использоваться с функциями манипуляции с mxArray. Если ваша S-функция содержит S-параметры-функции, используйте функции манипуляции с mxArray в методе mdlCheckParameters, чтобы проверять значения S-параметра-функции. Смотрите S-функцию sfun_runtime3.c для примера

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

if (!mxIsChar(ssGetSFcnParam(S, 0)) ||
     (nu=mxGetNumberOfElements(ssGetSFcnParam(S, 0))) < 2) {
     ssSetErrorStatus(S,"1st parameter to S-function must be a "
       "string of at least 2 '+' and '-' characters");
     return;
}

mxArrays Используя 32-битные API

Чтобы написать программы C/C++, которые работают с MATLAB структура данных mxArray, используйте матричные API C. C матричные API поддерживают 32-битную и 64-битную индексацию. По умолчанию ваши S-функции создаются с помощью 32-битных API. Проверяйте файлы MEX Обновления, чтобы Использовать 64-битный API (MATLAB), чтобы видеть, как обновить ваши существующие файлы MEX.

Чтобы проверять использование 32-битных API, можно запуститься, S-функция обновляют советника от Analysis> Model Advisor> Upgrade Advisor.

Если вы создаете свой код с -largeArrayDims, и ваш код заполняет поле размерности структуры ssParamRec с размерностями mxArray, запуская R2018a, вы больше не можете бросать возвращаемое значение mxGetDimensions к int_T pointer, потому что mxGetDimensions теперь возвращает указатель size_T на 64-битных платформах. Как обходное решение, создайте временную копию типа int_T и присвойте его полю dims структуры ssParamRec.

Замена:С:
ssParamRec p;
p.dims = (int_T *) mxGetDimensions(ssGetSFcnParam(S, 0));
// Set up other fields of p
if (!ssSetRunTimeParamInfo(S, 0, &p)) {
       free(dims);
       return;
}
free(dims); // free memory allocated for dimensions
ssParamRec p;
const mxArray* mxPrm = ssGetSFcnParam(S, 0);
const mwSize* mxDims = mxGetDimensions(mxPrm);
const mwSize mxNumDims = mxGetNumberOfDimensions(mxPrm);
mwSize idx;
int_T * dims = malloc(sizeof(int)*mxNumDims);
for (idx=0; idx < mxNumDims; idx++)
{
   dims[idx] = mxDims[idx];
} 

p.dims = dims;
// Set up other fields of p

if (!ssSetRunTimeParamInfo(S, 0, &p)) {
       free(dims);
       return;
}
free(dims); // free memory allocated for dimensions

mxArrays Используя чередованное комплексное представление

До версии 9.4 (R2018a) MATLAB, mxArrays используемое отдельное комплексное представление, где действительные и мнимые части комплексного числа хранились отдельно. Стартовая версия 9.4 (R2018a), MATLAB использует чередованное представление, чтобы хранить комплексные данные, где действительные и мнимые части комплексные числа хранятся вместе. Для S-функций, чтобы управлять mxArrays, больше нет потребности преобразовать данные от отдельного до чередованного комплекса. Смотрите Поддержку MATLAB Чередованного Комплексного API в MEX-функциях (MATLAB) для получения дополнительной информации о том, как обновить ваш код.

Примечание

Чтобы хранить комплексные данные для сигналов ввода и вывода или DWorks, Simulink использует чередованное представление.

Автоматически проверять ваши S-функции на потенциале чередовало проблемы комплексных данных, используйте Check model for S-function upgrade issues под Analysis> Model Advisor> Upgrade Advisor.

Следующий пример кода копирует значение параметров от mxArray до вывода S-функции. В этом примере размерности, тип данных и сложность параметра и выходного аргумента обеспечены, чтобы быть тем же самым. Например, если параметр является комплексным, выходной сигнал является комплексным. Если параметр действителен, выходной сигнал действителен. Для примера ниже, тип данных и параметра и вывода двойное (real_T). Перед R2018a вы могли использовать mxGetPr и mxGetPr, чтобы скопировать действительные и мнимые части комплексные данные отдельно. С чередованным комплексным представлением можно использовать memcpy, который является одной инструкцией по копии.

Замена:С:
    real_T            *y     = ssGetOutputPortRealSignal(S,0);
    boolean_T   yIsComplex = ssGetOutputPortComplexSignal(S, 0) == COMPLEX_YES;
    int_T             yWidth = ssGetOutputPortWidth(S,0);

    const real_T      *pr    = mxGetPr(ssGetSFcnParam(S, 0));          
    const real_T      *pi    = mxGetPi(ssGetSFcnParam(S, 0));

   int               i;

    for (i = 0; i < yWidth; i++) {

        int_T idx = (yIsComplex)  ? 2*i : i;
        y[idx] =  pr[idx];

        if(yIsComplex){
             y[idx+1] = pi[idx];
        }
    }
    real_T            *y     = ssGetOutputPortRealSignal(S,0);
    boolean_T   yIsComplex = ssGetOutputPortComplexSignal(S, 0) == COMPLEX_YES;
    int_T             yWidth = ssGetOutputPortWidth(S,0);

    mxComplexDouble *pc;
    mxDouble *pr;

   if (yIsComplex) {

        pc = mxGetComplexDoubles(ssGetSFcnParam(S, 0));
        memcpy(y, pc, yWidth*sizeof(mxComplexDouble));

   } else {

       pr = mxGetDoubles(ssGetSFcnParam(S, 0));
       memcpy(y, pr, yWidth*sizeof(mxDouble)); 

   }
[a]

A 

sizeof(mxComplexDouble)=2*sizeof(mxDouble)=2*sizeof(real_T)

Смотрите также

|

Похожие темы