Текущий раздел:

Описания RDS

Руководство программиста

Глава 2. Создание моделей блоков

§2.5. Статические переменные блоков

§2.5.7. Использование входов со связанными сигналами

Полный исходный текст на языке C++ для библиотеки (DLL) с моделью, вычисляющей произведение минимального элемента одной входной матрицы вещественных чисел и максимального элемента другой с использованием связанных сигналов для блокировки ненужных вычислений.

      // Использование связанных сигналов
      #include <windows.h>
      #include <RdsDef.h>
      // Подготовка описаний сервисных функций
      #define RDS_SERV_FUNC_BODY GetInterfaceFunctions
      #include <RdsFunc.h>

      // Глобальная переменная для значения ошибки
      double DoubleErrorValue;

      //========== Главная функция DLL ==========
      int WINAPI DllMain(HINSTANCE /*hinst*/,
                               unsigned long reason,
                               void* /*lpReserved*/)
      { if(reason==DLL_PROCESS_ATTACH) // Загрузка DLL
          { // Получение доступа к функциям RDS
            if(!GetInterfaceFunctions())
              RDS_SERV_ERROR_MSGW // Сообщение: старая версия RDS
            else
              rdsGetHugeDouble(&DoubleErrorValue); // Получение значения-индикатора ошибки
          }
        return 1;
      }
      //========= Конец главной функции =========

      //===== Произведение максимального ========
      //====== и минимального элементов =========
      extern "C" __declspec(dllexport)
        int RDSCALL TestMatMinMax(int CallMode,
                                   RDS_PBLOCKDATA BlockData,
                                   LPVOID ExtParam)
      {
      // Макроопределения для статических переменных
      #define pStart  ((char *)(BlockData->VarTreeData))
      #define Start (*((char *)(pStart)))
      #define Ready (*((char *)(pStart+RDS_VSZ_S)))
      #define s1 (*((char *)(pStart+2*RDS_VSZ_S)))
      #define s2 (*((char *)(pStart+3*RDS_VSZ_S)))
      #define pM1 ((void **)(pStart+4*RDS_VSZ_S))
      #define pM2 ((void **)(pStart+4*RDS_VSZ_S+RDS_VSZ_M))
      #define M1min (*((double *)(pStart+4*RDS_VSZ_S+2*RDS_VSZ_M)))
      #define M2max (*((double *)(pStart+4*RDS_VSZ_S+2*RDS_VSZ_M+ \
                    RDS_VSZ_D)))
      #define y (*((double *)(pStart+4*RDS_VSZ_S+2*RDS_VSZ_M+ \
                2*RDS_VSZ_D)))

        switch(CallMode)
          { // Проверка типа переменных
            case RDS_BFM_VARCHECK:
              if(strcmp((char*)ExtParam,"{SSSSMDMDDDD}")==0)
                return RDS_BFR_DONE;
              return RDS_BFR_BADVARSMSG;

            // Выполнение такта моделирования
            case RDS_BFM_MODEL:
              if(s1) // Изменилось значение входа M1
                { // Необходимо найти новый минимальный элемент
                  s1=0; // Сброс сигнала
                  if(RDS_ARRAYEXISTS(pM1)) // Матрица M1 не пуста
                    { // Вспомогательные переменные
                      int m1count;
                      double *m1data;
                      // Число элементов в матрице
                      m1count=RDS_ARRAYROWS(pM1)*RDS_ARRAYCOLS(pM1);
                      // Получить указатель на первый элемент
                      m1data=(double*)RDS_ARRAYDATA(pM1);
                      // Поиск минимального элемента
                      M1min=DoubleErrorValue;
                      for(int i=0;i<m1count;i++)
                        if(m1data[i]!=DoubleErrorValue &&
                           (M1min==DoubleErrorValue || M1min>m1data[i]))
                          M1min=m1data[i];
                    }
                  else // Матрица M1 пуста
                    M1min=DoubleErrorValue;
                } // if(s1)
              if(s2) // Изменилось значение входа M2
                { // Необходимо найти новый максимальный элемент
                  s2=0; // Сброс сигнала
                  if(RDS_ARRAYEXISTS(pM2)) // Матрица M2 не пуста
                    { // Вспомогательные переменные
                      int m2count;
                      double *m2data;
                      // Число элементов в матрице
                      m2count=RDS_ARRAYROWS(pM2)*RDS_ARRAYCOLS(pM2);
                      // Получить указатель на первый элемент
                      m2data=(double*)RDS_ARRAYDATA(pM2);
                      // Поиск максимального элемента
                      M2max=DoubleErrorValue;
                      for(int i=0;i<m2count;i++)
                        if(m2data[i]!=DoubleErrorValue &&
                           (M2max==DoubleErrorValue || M2max<m2data[i]))
                          M2max=m2data[i];
                    }
                  else // Матрица M2 пуста
                    M2max=DoubleErrorValue;
                } // if(s2)
              // Значения M1min и M2max определены –
              // вычисление произведения
              if(M1min!=DoubleErrorValue && M2max!=DoubleErrorValue)
                y=M1min*M2max;
              else
                y=DoubleErrorValue;
              break;
          }
        return RDS_BFR_DONE;
      // Отмена макроопределений
      #undef y
      #undef M2max
      #undef M1min
      #undef pM2
      #undef pM1
      #undef s2
      #undef s1
      #undef Ready
      #undef Start
      #undef pStart
      }
      //=========================================