Навигация:
<< >> Оглавление Указатель
Текст С++

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

Изменения, внесенные в старые версии этих же моделей, описанные в §2.6.3, выделены цветом.

  // Связь между блоками через динамическую переменную
  // (добавлена функция настройки) 
  #include <windows.h>
  #include <math.h>
  #include <RdsDef.h>
  // Подготовка описаний сервисных функций
  
  #include <RdsFunc.h>

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

  //=========== Блок-передатчик =============
  extern "C" __declspec(dllexport)
       int  TestTunnelIn(int CallMode,
                                 BlockData,
                                 ExtParam)
  {
  // 
  #define pStart  ((char *)(BlockData->VarTreeData))
  #define Start (*((char *)(pStart)))
  #define Ready (*((char *)(pStart+RDS_VSZ_S)))
  #define x (*((double *)(pStart+2*RDS_VSZ_S)))
    // Вспомогательная переменная – указатель на структуру подписки
     Link;
    // Вспомогательная переменная – структура описания блока
     Descr;
    // Вспомогательная переменная – указатель на строку 
    char *str;

    switch(CallMode)
      { // Очистка
        case :
          // Запомненный указатель на структуру подписки
          Link=()BlockData->BlockData;
          // Удалить созданную динамическую переменную
          (Link);
          break;

        // Проверка типа статических переменных
        case :
          if(strcmp((char*)ExtParam,"{SSD}")==0)
            return ;
          return ;

        // Переход в режим моделирования
        case :
          // Запомненный указатель на структуру подписки
          Link=()BlockData->BlockData;
          if(Link!=NULL) // Динамическая переменная была создана
            { // Заполнить структуру описания блока
              Descr.servSize=sizeof(Descr);
              (BlockData->Block,&Descr);
              // Сравнить имя переменной с текстом комментария
              if(strcmp(Link->VarName,Descr.BlockComment)!=0)
                { // Имя переменной не совпадает с комментарием -
                  // переменная будет удалена
                  (Link);
                  // Очистить запомненный указатель на структуру
                  // подписки
                  BlockData->BlockData=NULL;
                }
            }
          break;

        // Запуск расчета
        case :
          if(BlockData->BlockData!=NULL) // Переменная была создана
            break;
          // Динамической переменной нет (не было или удалена
          // в реакции на RDS_BFM_CALCMODE) - надо создать новую.
          // Сначала надо получить комментарий блока
          Descr.servSize=sizeof(Descr);
          (BlockData->Block,&Descr);
          if(*Descr.BlockComment==0) // Комментарий пуст
            break;
          // Комментарий блока – не пустая строка. Создаем переменную.

          Link=(,
                                       Descr.BlockComment,
                                       "D",
                                       TRUE,
                                       NULL);
          // Запомнить новый указатель на структуру подписки
          BlockData->BlockData=Link;
          // В конце реакции на запуск расчета нет оператора break,
          // поэтому сразу после нее выполнится реакция на
          // такт расчета (чтобы начальное значение входа
          // записалось в динамическую переменную)

        // Выполнение такта моделирования
       case :
          // Запомненный указатель на структуру подписки
          Link=()BlockData->BlockData;
          // Проверка существования переменной
          if(Link!=NULL && Link->Data!=NULL)
            { // Переменная существует – привести указатель
              // на область данных переменной к типу "double*"
              double *pV=(double*)Link->Data;
              if(*pV!=x) // Значение входа изменилось
                { // Записать в динамическую переменную новое
                  // значение входа
                  *pV=x;
                  // Уведомить всех подписчиков об изменении
                  // переменной
                  (Link);
                }
            }
          break;

        // Реакция на функцию настройки 
        case :
          // Получение текущего текста комментария блока 
          Descr.servSize=sizeof(Descr);
          (BlockData->Block,&Descr);
          // Открытие диалогового окна для ввода строки 
          str=("Переменная связи", // Заголовок окна 
                             "Имя переменной:",  // Заголовок поля 
                             Descr.BlockComment, // Исходный текст 
                             150);               // Ширина поля 
          if(str!=NULL) // Пользователь нажал "OK" 
            { // Установить новый комментарий 
              (BlockData->Block,str);
              // Освободить динамическую строку 
              (str);
              // Информировать RDS об изменениях 
              return ;
            }
          break;
      }
    return ;
  // Отмена макроопределений
  #undef x
  #undef Ready
  #undef Start
  #undef pStart
  }
  //=========================================

  //============ Блок-приемник ==============
  extern "C" __declspec(dllexport)
       int  TestTunnelOut(int CallMode,
                                  BlockData,
                                  ExtParam)
  {
  // 
  #define pStart ((char *)(BlockData->VarTreeData))
  #define Start (*((char *)(pStart)))
  #define Ready (*((char *)(pStart+RDS_VSZ_S)))
  #define y (*((double *)(pStart+2*RDS_VSZ_S)))
    // Вспомогательная переменная – указатель на структуру подписки
     Link;
    // Вспомогательная переменная – структура описания блока
     Descr;
    // Вспомогательная переменная – указатель на строку 
    char *str;

    switch(CallMode)
     { // Очистка
        case :
          // Запомненный указатель на структуру подписки
          Link=()BlockData->BlockData;
          // Прекратить подписку на переменную
          (Link);
          break;

        // Проверка типа статических переменных
        case :
          if(strcmp((char*)ExtParam,"{SSD}")==0)
            return ;
          return ;

        // Запуск расчета
        case :
          // Запомненный указатель на структуру подписки
          Link=()BlockData->BlockData;
          // Получение описания блока (с комментарием)
          Descr.servSize=sizeof(Descr);
          (BlockData->Block,&Descr);
          // Проверка наличия комментария
          if(*Descr.BlockComment==0) // Пустая строка
            { // Прекратить подписку на переменную
              (Link);
              // Очистить запомненный указатель на структуру подписки
              BlockData->BlockData=NULL;
              break;
            }
          // Если переменной нет (Link==NULL) или ее имя не
          // соответствует комментарию блока (strcmp... !=0),
          // нужно подписаться на новую переменную
          if(Link==NULL || 
             strcmp(Link->VarName,Descr.BlockComment)!=0)
            { // Прекратить подписку на старую переменную
              (Link);
              // Подписаться на новую
              Link=(,
                                            Descr.BlockComment,
                                            "D",
                                            FALSE);
              // Запомнить новый указатель на структуру подписки
              BlockData->BlockData=Link;
            }
          // В конце реакции на запуск расчета нет оператора break,
          // поэтому сразу после нее выполнится реакция на
          // изменение динамической переменной (чтобы ее значение
          // было немедленно передано на выход блока)

        // Реакция на изменение динамической переменной
        case :
          // Запомненный указатель на структуру подписки
          Link=()BlockData->BlockData;
          // Проверка существования переменной
          if(Link!=NULL && Link->Data!=NULL)
            { // Присвоить выходу блока значение динамической
              // переменной
              y=*(double*)Link->Data;
              // Взвести сигнал Ready, чтобы значение выхода
              // было передано по связям
              Ready=1;
            }
          break;

        // Реакция на функцию настройки 
        case :
          // Получение текущего текста комментария блока 
          Descr.servSize=sizeof(Descr);
          (BlockData->Block,&Descr);
          // Открытие диалогового окна для ввода строки 
          str=("Переменная связи", // Заголовок окна 
                             "Имя переменной:",  // Заголовок поля 
                             Descr.BlockComment, // Исходный текст 
                             150);               // Ширина поля 
          if(str!=NULL) // Пользователь нажал "OK" 
            { // Установить новый комментарий 
              (BlockData->Block,str);
              // Освободить динамическую строку 
              (str);
              // Информировать RDS об изменениях 
              return ;
            }
          break;
      }

    return ;
  // Отмена макроопределений
  #undef y
  #undef Ready
  #undef Start
  #undef pStart
  }
  //=========================================


<< >> Оглавление Указатель