Руководство программиста
Глава 2. Создание моделей блоков
В главе подробно разбираются различные аспекты написания моделей блоков, реакции на системные события, вызов сервисных функций RDS. Приводятся примеры исходных текстов моделей на языке C++ с подробным описанием работы этих моделей.
§2.1. Программы моделей и DLL
Описывается общий принцип размещения моделей в динамически подключаемых библиотеках (DLL) и способ компиляции примеров моделей, рассматриваемых в этой главе.
Модель блока в RDS – это экспортированная из динамически подключаемой библиотеки (DLL) функция с определенным набором параметров. В одной библиотеке может находится несколько моделей, поэтому некоторые действия, общие для всех моделей (инициализация, регистрация функций блоков и т.п.), часто выносятся в главную функцию DLL (обычно она называется DllEntryPoint или DllMain, но может иметь и другое имя). RDS всегда загружает DLL с моделями блоков динамически, при помощи функции Windows API LoadLibrary, и всегда выгружает их перед загрузкой новой схемы, даже если в новой схеме используются те же самые модели.
Поскольку RDS существует в тридцатидвухбитной («Rds.exe») и шестидесятичетырехбитной («Rds64.exe») версиях, DLL с моделями блоков тоже желательно создавать в двух версиях
Все примеры, приведенные ниже, написаны на C или C++ и, в основном, рассчитаны на компилятор GCC, например MinGW.OSDN (https://osdn.net/projects/mingw/⇗), MinGW-w64 (https://www.mingw-w64.org/⇗), tdm-gcc (https://jmeubank.github.io/tdm-gcc/⇗). Можно также использовать OpenWatcom C++ (http://www.openwatcom.org⇗), Borland C++ 5.5 и другие консольные компиляторы C/C++. Для того, чтобы консольный компилятор создал именно DLL, а не обычный исполняемый файл (EXE), который он формирует по умолчанию, можно использовать следующие параметры командной строки, в которые нужно подставить пути к папкам и компилируемым файлам, как, например, показано ниже (для GCC):
- для компиляции
- -shared -fpermissive -c -I"папки_заголовков" "файл_C"
- для окончательной сборки DLL
- -shared -static -static-libgcc -static-libstdc++ -o файл_DLL файл_OBJ.o
Параметры командной строки основных используемых компиляторов для сборки DLL можно увидеть в настройках стандартных модулей автокомпиляции RDS.
В командной строке для компиляции вместо слова «папки_заголовков» следует подставить полные пути ко всем папкам, в которых находятся заголовочные файлы с описаниями констант и функций стандартных библиотек C (обычно они входят в состав компилятора), а также путь к папке «\Include» из состава RDS, а вместо «файл_C» – путь к файлу исходного текста программы. В командной строке редактора связей вместо слова «папки_библиотек» следует подставить путь к стандартным библиотекам компилятора, вместо «файл_OBJ» – путь к объектному файлу, сформированному компилятором, и вместо «файл_DLL» – путь к библиотеке DLL, которую должен создать редактор связей. Пути могут быть полными (с указанием всех вложенных папок от буквы диска) или относительными (относительно текущей папки), это зависит от конкретного компилятора. Например, если GCC установлен в папку «C:\Prog\MinGW\bin», RDS – в папку «C:\RDS», а исходный текст программы находится в файле «model.cpp» в текущей папке, команды для вызова компилятора и редактора связей будут выглядеть так (цветом выделены подставленные пути и имена файлов):
C:\Prog\MinGW\bin\g++.exe -shared -fpermissive -c -I"C:\RDS\Include" model.cpp
C:\Prog\MinGW\bin\g++.exe -shared -static -static-libgcc -static-libstdc++ -o model.dll model.o
При этом созданная в результате компиляции библиотека будет размещаться в файле «model.dll» в текущей папке.
Для рассматриваемых примеров можно использовать и другие компиляторы. Для каждого компилятора нужно подобрать параметры командной строки, которые укажут ему на необходимость создать именно DLL, а не исполняемый exe-файл, указать пути к папкам с файлами заголовков RDS, перечислить необходимые для компиляции библиотеки и т.д. Эта информация содержится в описании каждого компилятора.
Многие модели блоков в этом руководстве написаны с использованием классов, поэтому для их сборки нужен именно компилятор C++. Тем не менее, при желании, модели блоков можно писать и на «чистом» C: обмен данными между RDS и моделью блока осуществляется только через структуры и функции обратного вызова, при этом классы и прочие расширения C++ не используются.
Можно писать модели блоков и на других языках, если, конечно, используемый компилятор поддерживает создание DLL и работу с функциями Windows API. Как правило, если компилятор позволяет обращаться к функциям API, он также позволит обратиться к сервисным функциям RDS – они имеют похожие типы вызова, описанные далее.