Skip to main content

Создание вызова функции из внешней библиотеки

Вопрос:

В документации декларируется возможность вызова функции из внешней библиотеки.
Подскажите, где найти подробности по правилам написания таких библиотек?

Ответ технической поддержки:

Сценарий добавления сторонних компонентов на Qt выглядит следующим образом:

  • Пользователь имеет Qt плагин со своими кастомными типами;
  • В Alpha.HMI пользователь добавляет ссылку на юнит (аналогично добавлению сторонних .NET модулей, Проект > Ссылки на юниты > Добавить из файла);
  • Типами (как и визуальными, так и не визуальными) можно пользоваться в HMI проекте.

По поводу п.1.

Во-первых, подключаемый модуль должен быть определен по механизмам плагинной системы Qt (добавить Q_PLUGIN_METADATA(IID "some_qt_plugin_data") в тип MyPlugin - объект плагина для QPluginLoader).
Помимо этого, нужно тип MyPlugin разметить атрибутом Q_CLASSINFO("<PLATFORMTAG>_UUID", "<UNIT_UUID>") - только тогда Alpha.HMI будет воспринимать Qt плагин как HMI юнит и сможет создать на него ссылку.

Во-вторых, нужно каждый экспортируемый в Alpha.HMI тип T разметить атрибутом Q_CLASSINFO("<PLATFORMTAG>_UUID", "<TYPE_UUID>") и зарегистрировать в конструкторе MyPlugin через вызов qRegisterMetaType<T*>().

В-третьих, собирать плагин нужно с динамически линкуемыми модулями Qt SDK; обязательно 5.x.x мажора, предпочтительно 5.15.2 версии, которая сейчас используется в Alpha.HMI.

Нужно сразу обозначить, что из определения кастомного T типа попадет в импорт Alpha.HMI, а что не попадет:

  • Публичные свойства, сигналы, слоты, методы - защищенные и приватные не будут учитываться;
  • В сигнатурах перечисленных мемберов для экспортируемости в Alpha.HMI, типы должны быть в рамках множества {bool, floating, integer, QDateTime, QString};
  • Экспортироваться будут только собственные мемберы типа T, унаследованные от базовых типов (например QWidget) пока что не будут учитываться;
  • Для создания экземпляра T на мнемосхеме будет использоваться только T::T() конструктор, поэтому аргументов либо не должно быть вовсе, либо они все должны иметь значения по умолчанию

NB: floating - float, double; integer - (u)int{8|16|32|64}_t.

Прикрепляю образец кода плагина Qt, который пригоден для импорта в Alpha.HMI через ссылки на юниты, а также сам проект с импортированной библиотекой.

По QT при сборке прошу учесть следующее:
Компилятор необходимо использовать gcc-5, к окружению особых требований нет.
Главное, от чего нужно отталкиваться во время сборки плагина - чтобы была бинарная совместимость с бинарями Qt 5  (лучше конечно с точностью до версии - 5.15.2), собранными вендором фреймворка для amd64 на базе gcc-5 (ровно такие Alpha.HMI и использует).
Уточняю, gcc-5 на MSVC-2019. Линковаться с CRT (Microsoft C Runtime) нужно динамически. Собирать нужно профиль Release, а не Debug, иначе в Alpha.HMI плагин не запустится.

Для создания .netcore библиотеки на линукс необходимо на машине с линукс установить dotnet-sdk, например, командой:
sudo apt-get update &&   sudo apt-get install -y dotnet-sdk-6.0 (или другую версию)
перейти в директорию, где планируется создать .netcore библиотеку, например:
cd testnetcore
создать проект по шаблону
dotnet new classlib
и выполнить компиляцию
dotnet run
После успешной компиляции, в папке testnetcore будет dll файл, который можно использовать в HMI.
Прикладываю пример проекта для линукс. Также, сообщаю, что для того, чтобы HMI смог работать с библиотекой, на машине должен быть установлен dotnet-runtime. Установить можно командой:
 sudo apt install dotnet-runtime-6.0. Прошу дать обратную связь по результату применения решения.
Библиотека должна компилироваться на той ОС, на которой будет использоваться. Если библиотека компилировался под Windows, под Linux она работать не будет.

Также прикрепляю пример библиотеки и проект в DevStudio СppLib. В текстовом файле описаны свойства сигнала, используемые при настройке через конфигуратор.