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

Полный исходный текст на языке C++ для библиотеки (DLL) с моделью блока, вычисляющего значение выхода «y» по формуле «y=K×x+C» и хранящего настроечные параметры в значениях по умолчанию входов «K» и «C»

  // Хранение настроек в значениях входов по умолчанию
  #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;
  }
  //========= Конец главной функции =========

  // Проверка наличия связи у входа блока
   CheckBlockInputConnection(
     Block,              // Идентификатор блока
    int num,                        // Номер входа
     pVarDescr)  // Указатель на структуру
            // описания переменной
  {  c;                // Идентификатор связи
     PtDescr; // Структура описания точки связи

    // Заполнение служебных полей структур их размерами
    PtDescr.servSize=sizeof(PtDescr);
    pVarDescr->servSize=sizeof(RDS_VARDESCRIPTION);

    // Получение описания переменной блока по номеру
    if((Block,num,pVarDescr)==NULL)
      return FALSE; // Нет такой переменной

    // Перебор всех связей, подключенных к этому блоку
    c=NULL;
    for(;;)
      { // Найти связь, следующую за c, и заполнить структуру
        // описания точки соединения PtDescr
        c=(Block,c,TRUE,FALSE,&PtDescr);
        if(c==NULL) // Больше нет связей
          break;
        // Найдена очередная связь – сравнение имени заданной
        // переменной с именем переменной точки этой связи
        if(strcmp(PtDescr.VarName,pVarDescr->Name)==0)
          return TRUE; // Имена совпали – есть связь, соединенная
                       // с переменной блока
      }
    // Все подключенные связи перебраны, а связь, подключенная
    // к заданной переменной так и не была найдена
    return FALSE;
  }
  //=========================================

  // Добавление поля для ввода или индикации вещественного параметра
  // 
  // 
  // 
   AddWinEditOrDisplayDouble(
     window, // Идентификатор объекта-окна
     Block,  // Блок
    int varnum,         // Номер переменной в блоке
    int ctrlnum,        // Идентификатор поля ввода в окне
    char *title)        // Заголовок поля или NULL
  { // Структура описания переменной блока
     VarDescr;
    // Проверка наличия связи у переменной varnum в блоке Block
    // и заполнение структуры VarDescr описанием переменной
     conn=CheckBlockInputConnection(Block,varnum,&VarDescr);

    if(conn) // К переменной подключена связь
      { // Вспомогательные переменные
        char *caption;  // Заголовок поля
        double *cur;    // Указатель на данные переменной
        // Заголовок поля формируется из имени переменной и
        // текста "подключена связь"
        caption=(title?title:VarDescr.Name,
                             " (подключена связь)",
                             FALSE);
        // Добавление поля для индикации текущего значения
        (window,0,ctrlnum,,
                       caption,80);
        // Освобождение динамически сформированной строки
        // заголовка поля
        (caption);
        // Получение указателя на данные переменной
        cur=(double*)(Block,varnum,NULL);
        // Проверка – переменная должна существовать и иметь тип double
        if(cur!=NULL && VarDescr.Type=='D')
          // Занесение текущего значения переменной в поле
          (window,ctrlnum,,*cur);
      }
    else // К переменной не подключена связь
      { // Вспомогательная переменная для значения по умолчанию
        char *defval;
        // Получение строки со значением переменной по умолчанию
        // (необходимо потом освободить при помощи rdsFree)
        defval=(Block,varnum,NULL);
        // Добавление поля для ввода параметра
        (window,0,ctrlnum,,
                       title?title:VarDescr.Name,80);
        // Занесение в поле ввода значения перменной по умолчанию
        (window,ctrlnum,,defval);
        // Освобождение динамически сформированной строки
        (defval);
      }
    // Возврат: TRUE – есть связь, FALSE – нет связи
    return conn;
  }
  //=========================================


  // Функция настройки K и C для модели блока y=Kx+C
  // 
  // 
  // 
   TestKxCSetup(
     Block,  // Идентификатор блока
    int numK,           // Номер переменной K в блоке
    int numC)           // Номер переменной C в блоке
  {  window; // Идентификатор вспомогательного объекта
     ok;            // Пользователь нажал "OK"
     K_conn,C_conn; // Флаги наличия связей у K и C

    // Создание окна
    window=(FALSE,-1,-1,"Kx+C");

    // Добавление полей для ввода или индикации K и C
    // (в зависимости от наличия связей)
    K_conn=AddWinEditOrDisplayDouble(window,Block,numK,1,NULL);
    C_conn=AddWinEditOrDisplayDouble(window,Block,numC,2,NULL);

    // Открытие окна
    ok=(window,NULL);
    if(ok)
      { // Нажата кнопка OK – запись параметров в блок
        if(!K_conn) // У K нет связи
          { // Получение строки из поля ввода
            char *str=(window,1,);
            // Установка значения переменной K по умолчанию
            (Block,numK,str);
          }
        if(!C_conn) // У С нет связи
          { // Получение строки из поля ввода
            char *str=(window,2,);
            // Установка значения переменной C по умолчанию
            (Block,numC,str);
          }
      }
    // Уничтожение окна
    (window);
    // Возвращаемое значение – истина, если нажата "OK"
    return ok;
  }
  //=========================================

  // Функция модели блока
  extern "C" __declspec(dllexport)
    int  TestKxC(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)))
  #define K (*((double *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D)))
  #define C (*((double *)(pStart+2*RDS_VSZ_S+2*RDS_VSZ_D)))
  #define y (*((double *)(pStart+2*RDS_VSZ_S+3*RDS_VSZ_D)))
    switch(CallMode)
      { // Проверка типа переменных
        case :
          if(strcmp((char*)ExtParam,"{SSDDDD}")==0)
            return ;
          return ;

        // Запуск расчета
        case :
          // Если это запуск с начала, взвести Start
          if((()ExtParam)->FirstStart)
            Start=1; // Модель запустится в первом же такте
          break;

        // Такт расчета
        case :
          y=K*x+C;
          break;

        // Функция настройки
        case :
          if(TestKxCSetup(BlockData->Block,3,4))
            { // Нажата “OK"
              Start=1; // Запустить модель в следующем такте
              return ;
            }
      }
    return ;
  // Отмена макроопределений
  #undef y
  #undef C
  #undef K
  #undef x
  #undef Ready
  #undef Start
  #undef pStart
  }
  //=========================================


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