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

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

  #include <windows.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;
  }
  //========= Конец главной функции =========

  // Класс личной области данных модуля автокомпиляции
  class 
  { private:
      // Пути
      char *CompPath;     // к компилятору
      char *LinkPath;     // к редактору связей (link)
      char *IncludePath;  // к файлам заголовков
      char *LibPath;      // к библиотекам
      // Нужно ли добавлять путь к exe-файлу компилятора и редактора связей
       CompSetPath,LinkSetPath;
      // Параметры командной строки
      char *CompParams;   // компилятора
      char *LinkParams;   // редактора связей
      // Параметры исходного текста
      char *DllMainName;  // имя главной функции DLL
      char *ModelFuncHdr; // заголовок функции модели
      char *Exported;     // экспортированное имя функции

      // Освободить все динамические строки
      void FreeAllStrings(void)
        { (CompPath);
          (LinkPath);
          (IncludePath);
          (LibPath);
          (CompParams);
          (LinkParams);
          (DllMainName);
          (ModelFuncHdr);
          (Exported);
        };

    public:
      // Чтение параметров модуля из INI-файла
      void ReadFromIni(const char *IniFileName);
      // Запись параметров модуля в INI-файл
      void WriteToIni(const char *IniFileName);
      // Настройка параметров модуля
      void Setup(const char *IniFileName);

      // Конструктор класса
      TCAutoCompData(void)
      { IncludePath=LibPath=NULL;
        CompSetPath=LinkSetPath=TRUE;
        #ifdef 
          CompPath=(
            "$RDS$\\mingw-w64\\bin\\g++.exe");
          LinkPath=(CompPath);
          CompParams=(
            "-Wall -m64 -g -I\"$RDSINCLUDE$\" -c \"$TEMP$\\$NAME$.cpp\" -o \"$TEMP$\\$NAME$.o\""
            );
          LinkParams=(
            "-shared -static -static-libgcc -static-libstdc++ -Wl,--dll \"$TEMP$\\$NAME$.o\" -o \"$TEMP$\\$NAME$.dll\" -s -m64 -luser32"
            );
          DllMainName=("extern \"C\" __declspec(dllexport) BOOL APIENTRY DllMain");
          ModelFuncHdr=(
            "extern \"C\" __declspec(dllexport) int RDSCALL autocompModelFunc"
            );
          Exported=("autocompModelFunc");
        #else
          CompPath=(
            "$RDS$\\tdm-gcc\\bin\\g++.exe");
          LinkPath=(CompPath);
          CompParams=(
            "-shared -fpermissive -c -I\"$RDSINCLUDE$\" \"$TEMP$\\$NAME$.cpp\""
            );
          LinkParams=(
            "-shared -static -static-libgcc -static-libstdc++ -o \"$TEMP$\\$NAME$.dll\" \"$TEMP$\\$NAME$.o\""
            );
          DllMainName=("extern \"C\" BOOL WINAPI DllMain");
          ModelFuncHdr=(
            "extern \"C\" __declspec(dllexport) int RDSCALL autocompModelFunc");
          Exported=("autocompModelFunc@12");
        #endif
      };
      // Деструктор класса
      ~TCAutoCompData(){ FreeAllStrings(); };
  };
  //=========================================

  // Запись параметров модуля в INI-файл
  void TCAutoCompData::WriteToIni(const char *IniFileName)
  {  ini=(TRUE);

    // Загружаем старый текст из файла во вспомогательный объект, если он есть
    if((IniFileName,NULL,NULL,NULL))
      (ini,RDS_HINI_LOADFILE,0,IniFileName);

    // Создаем секцию [Paths...]
    (ini,,0,"Paths" );
    // Записываем в нее пути
    (ini,"Compiler",CompPath);
    (ini,"Linker",LinkPath);
    (ini,"Include",IncludePath);
    (ini,"Lib",LibPath);
    (ini,"CompilerToPaths",CompSetPath);
    (ini,"LinkerToPaths",LinkSetPath);

    // Создаем секцию [Params...]
    (ini,,0,"Params" );
    // Записываем в нее параметры командной строки
    (ini,"Compiler",CompParams);
    (ini,"Linker",LinkParams);

    // Создаем секцию [Func...]
    (ini,,0,"Func" );
    // Записываем в нее остальные параметры
    (ini,"DllMain",DllMainName);
    (ini,"ModelFunc",ModelFuncHdr);
    (ini,"Exported",Exported);

    // Сохраняем получившееся в файл
    (ini,,0,TCAUTOCOMP_INI);

    // Уничтожение вспомогательного объекта
    (ini);
  }
  //=========================================

  // Чтение параметров модуля из INI-файла
  void TCAutoCompData::ReadFromIni(const char *IniFileName)
  {  ini=(TRUE);

    // Загружаем текст из файла во вспомогательный объект
    (ini,,0,IniFileName);
    // Проверяем, нет ли ошибок
    if((ini,)) // Ошибка
      return;

    // Читаем строки из секции [Paths...]
    if((ini,"Paths" ))
      { char *CompPath_old=CompPath, // Старые значения
             *LinkPath_old=LinkPath,
             *IncludePath_old=IncludePath,
             *LibPath_old=LibPath;
        // Загружаем новые строки
        CompPath=((ini,"Compiler",CompPath_old,NULL));
        LinkPath=((ini,"Linker",LinkPath_old,NULL));
        IncludePath=((ini,"Include",IncludePath_old,NULL));
        LibPath=((ini,"Lib",LibPath_old,NULL));
        // Освобождаем старые строки
        (CompPath_old);
        (LinkPath_old);
        (IncludePath_old);
        (LibPath_old);
        // Добавление в пути
        CompSetPath=(ini,"CompilerToPaths",CompSetPath);
        LinkSetPath=(ini,"LinkerToPaths",LinkSetPath);
      }

    // Читаем строки из секции [Params...]
    if((ini,"Params" ))
      { char *CompParams_old=CompParams, // Старые значения
             *LinkParams_old=LinkParams;
        // Загружаем новые строки
        CompParams=((ini,"Compiler",CompParams_old,NULL));
        LinkParams=((ini,"Linker",LinkParams_old,NULL));
        // Освобождаем старые строки
        (CompParams_old);
        (LinkParams_old);
      }

    // Читаем строки из секции [Func...]
    if((ini,"Func" ))
      { char *DllMainName_old=DllMainName, // Старые значения
             *ModelFuncHdr_old=ModelFuncHdr,
             *Exported_old=Exported;
        // Загружаем новые строки
        DllMainName=((ini,"DllMain",DllMainName_old,NULL));
        ModelFuncHdr=((ini,"ModelFunc",ModelFuncHdr_old,NULL));
        Exported=((ini,"Exported",Exported_old,NULL));
        // Освобождаем старые строки
        (DllMainName_old);
        (ModelFuncHdr_old);
        (Exported_old);
      }
    // Вспомогательный объект больше не нужен
    (ini);
  }
  //=========================================

  // Настройка модуля автокомпиляции
  // 
  // 
  // 
  void TCAutoCompData::Setup(const char *IniFileName)
  {  window;	// Объект-окно
    const char exefilter[]=	// Фильтр для диалога выбора файла
           "Исполняемые файлы (*.exe)|*.exe\nВсе файлы|*.*";

    // Создание окна
    window=(TRUE,-1,-1,"Параметры модуля");

    // Создание вкладки
    (window,0,"Пути");

    // Поле ввода выбора EXE-файла компилятора
    (window,0,1,,
        "Компилятор:",300);
    (window,1,,exefilter);
    (window,1,,CompPath);

    // Нужно устанавливать путь?
    (window,0,100,,
        "Добавлять папку в путь",300);
    (window,100,,CompSetPath);

    // Поле ввода выбора EXE-файла редактора связей
    (window,0,2,,
        "Редактор связей:",300);
    (window,2,,exefilter);
    (window,2,,LinkPath);

    // Нужно устанавливать путь?
    (window,0,200,,
        "Добавлять папку в путь",300);
    (window,200,,LinkSetPath);

    // Выбор папки файлов заголовков
    (window,0,3,,
        "Папка заголовков:",300);
    (window,3,,IncludePath);

    // Выбор папки файлов библиотек
    (window,0,4,,
        "Папка библиотек:",300);
    (window,4,,LibPath);

    // Создание вкладки
    (window,1,"Параметры");

    // Параметры командной строки компилятора
    (window,1,5,,
        "Параметры компилятора:",300);
    (window,5,,3*24);// Высота
    (window,5,,CompParams);

    // Параметры командной строки редактора связей
    (window,1,6,,
        "Параметры редактора связей:",300);
    (window,6,,3*24);// Высота
    (window,6,,LinkParams);

    // Создание вкладки
    (window,2,"Описания");

    // Имя главной функции
    (window,2,7,,
        "Имя главной функции DLL:",300);
    (window,7,,DllMainName);

    // Заголовок модели
    (window,2,8,,
        "Заголовок функции модели:",300);
    (window,8,,2*24);// Высота
    (window,8,,ModelFuncHdr);

    // Экспортированное имя
    (window,2,9,,
        "Экспортированное имя:",300);
    (window,9,,Exported);

    // Открытие окна
    if((window,NULL)) // Нажата OK
      { // Освобождаем старые строки параметров
        FreeAllStrings();

        // Делаем динамические копии всех строк из полей ввода
        // и присваиваем их полям класса
        #define GETDYNRELPATH(x) (x,(),NULL)
          CompPath=GETDYNRELPATH((window,1,));
          LinkPath=GETDYNRELPATH((window,2,));
          IncludePath=GETDYNRELPATH((window,3,));
          LibPath=GETDYNRELPATH((window,4,));
        #undef GETDYNRELPATH

        CompParams=((window,5,));
        LinkParams=((window,6,));
        DllMainName=((window,7,));
        ModelFuncHdr=((window,8,));
        Exported=((window,9,));

        CompSetPath=(window,100,);
        LinkSetPath=(window,200,);

        // Запись изменившихся параметров в INI-файл
        WriteToIni(IniFileName);
      }
    // Уничтожение окна
    (window);
  }
  //=========================================

  // Функция модуля автокомпиляции
  extern "C" __declspec(dllexport) int  TestCAutoComp(
      int CallMode,                   // Событие
       ModuleData, // Данные модуля
       ExtParam)                // Дополнительные параметры
  { // Приведение указателя на личную область данных
    // к правильному типу
     *data=(*)(ModuleData->ModuleData);

    switch(CallMode)
      { // Инициализация модуля
        case :
          // Создание личной области данных модуля
          ModuleData->ModuleData=data=new ();
          // Чтение параметров из INI-файла
          data->ReadFromIni(ModuleData->DataFile);
          break;

        // Очистка данных модуля
        case :
          delete data;	// Удаление личной области модуля
          break;

        // Вызов окна настройки модуля
        case :
          data->Setup(ModuleData->DataFile);
          break;
      }
    return RDS_COMPR_DONE;
  }
  //=========================================


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