Загрузка актора на лету

Модель программирования Actor Framework
Ответить
Аватара пользователя
Usss
I/O
I/O
Сообщения: 144
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2018

Загрузка актора на лету

Сообщение Usss »

Идея в том, чтобы во время исполнения программы загружать скомпилированные акторы из известной папки. У меня все акторы являются потомком одного мастер-актора. Это прописано в иерархии класса. Мне не нравится то, как фреймворк плодит кучу классов для ввода-вывода данных, поэтому я сделал мастер-актор, который обеспечивает обмен между всем акторами через тип variant. Проблемы две.
1 Я вызываю nested акторы, предварительно объединив их в массив (скрин 2). При этом в индикаторе appended array 3 мы видим, что выходящий класс превратился в класс мастер-актора (т.е. если бы я все сделал без мастер-актора, то на его месте был бы стандартный класс Actor). Проблема возникает когда я создаю Packed library из nested акторов. Создаю точно такой-же массив как скрине 2 из скомпилированных акторов, но в appended array 3 уже не появляется их общий родительский класс, а появляется стандартный пустой класс (скрин 4). В итоге у меня конфликт типов данных и nested акторы не запускаются.
2 Моя идеология предполагает, что родитель вызывает nested акторы, которых заранее нет в памяти программы. Они должны загружаться из скомпилированных библиотек. Нужные мне vi, которые посылают сообщения и должны выполняться из главного актора, находятся в папке с известным именем. Пока это обычный проект, я могу их найти через стандартную функцию поиска файлов. Но когда это будет скомпилированная библиотека, как их найти?
Вложения
Рис1 Иерархия классов
Рис1 Иерархия классов
Рис 2 Массив акторов
Рис 2 Массив акторов
2.png (11.13 КБ) 123 просмотра
Рис 3 Мастер-актор
Рис 3 Мастер-актор
3.png (4.95 КБ) 123 просмотра
Рис 4 Вместо мастер-актора загрузилась пустышка
Рис 4 Вместо мастер-актора загрузилась пустышка
4.png (4.34 КБ) 123 просмотра
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5077
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 14 раз
Поблагодарили: 25 раз

Re: Загрузка актора на лету

Сообщение IvanLis »

Я сам подобного не проделывал, необходимости подобной не было, посмотрите Actor Framework from basic to PPL plugins
Аватара пользователя
Kosist

Activity Gold
expert
expert
Сообщения: 1085
Зарегистрирован: 21 фев 2011, 23:44
Награды: 2
Версия LabVIEW: 2013-2020
Благодарил (а): 4 раза
Поблагодарили: 5 раз
Контактная информация:

Re: Загрузка актора на лету

Сообщение Kosist »

Сначала простая часть - загрузка класса с диска. Для этого есть стандартные функции загрузки класса. Если класс находится в ppl (Project Packed Library), то в палете File I/O -> Advanced File Functions -> Packed Library есть тоже функции которые можно использовать.
Но вот в целом плагиновая архитектура - та еще головная боль.
Тут есть два пути - использовать классы "в сыром виде", или же в виде запакованых библиотек (ppl).
В обох случаях залог успеха - это добиться того, чтобы при динамической загрузке класса в памяти не возникало конфликтов, т.е. нельзя загружать те виайки, которые уже загружены в память самим exe.
Это главная проблема для использования классов "в сыром виде". Достичь этого можно таким способом, что Вы отдельно билдите приложение, и отдельно билдите Source Distribution классов. Но при этом, исключаете из билда все то, что уже включено в билд приложения. В результате, класс после билда обычно нерабочий сам по себе - ведь ему нехватает "общих" виаек с целым приложением.
Другой способ - это ppl. Главный недостаток ppl это то, что их нельзя переносить в другие версии :labview: , т.к. по сути это уже скомпилируемый код. Таким образом, сделав проект с использованием ppl, например, в :labview: 2018, Вы не откроете его так легко в :labview: 2020. Нужно будет билдить опять ppl минимум, а максимум - перелинковывать вручную их в проекте.
Но в случае ppl тоже должно работать правило что общие библиотеки не должны подгружаться многократно. Нужно найти "самостоятельные" библиотеки, которые не зависят от иных библиотек, и билдить ppl сначала с них. Потом - эти библиотеки поменять в коде на ppl, и начать билдить библиотеки которые уже зависят от ppl. При билде нужно ставить галочку Exclude Shared Libraries - таким образом ppl из зависимостей не будет включено в билд этих библиотек. И т.д., идете снизу вверх - сначала "независимые" библиотеки, потом дальше вверх по дереву зависимостей.
Например, LibA содержить класс Shared.lvclass, и LibB тоже использует класс Shared.lvclass. Если просто сбилдить LibA в отдельную ppl, и LibB в отдельную ppl, то обе либки будут содержать класс Shared.lvclass - но для :labview: это уже будут разные классы. А вот если сначала в исходнике поместить Shared.lvclass в отдельную либку, из нее сделать ppl, а потом сделать ppl-ки с LibA и LibB (при этом сделать Exclude Shared libs), то уже все будет нормально.
В случае Actor Framework - нужно вначале сбилдить ppl из самой корневой либки Actor Framework, и поменять на нее "исходник" (это, кстати, самое легкое - ПКМ на либке -> Replace by Packed Library). А потом билдить дальше.
Чтобы не возникало конфликтов, разные библиотеки лучше билдить из-под отдельных проектов.
В итоге, Ваше приложение потом будет зависеть от ppl, и Вы сможете сбилдить приложение которое будет их подгружать динамически.
Советую попробовать это сделать на маленьком, пробном проекте - чтобы Вы почувствовали что и как работает. Ну, и менять код на ppl лучше в самом конце, когда проект в исходнике работает полностью. Т.к. дебажить ppl - это то еще удовольствие...
Мы делили апельсин - много наших полегло...
Ответить

Вернуться в «Actor Framework»