|
|
|
Теория плагинов30.04.2010, 17:02. Показов 34310. Ответов 40
Метки нет (Все метки)
Всем привет.
Для одной моей проги, нужно реализовать поддержку плагинов. Плагины предполагаются простенькие, написанные на Си. То, что плагин, это просто .so файл - понятно. То, что прога может дергать из .so файла функции - тоже понятно. 1. Непонятно то, как сам плагин сможет дергать функции из программы? 2. Программа написана на С++, но плагины предполагаю писать на Си, во избежания бинарной несовместимости. В этом случае, какие сложности могут возникнуть? 3. Еще непонятно, каким образом "разделять" плагины, ведь их может быть несколько? 4. И еще непонятно, каким образом программе "сообщить" какие функции дергать из конкретного плагина? 5. И еще непонятно, каким образом плагин, сможет дергать функции из другого плагина? Нужна теоретическая подкова ![]() Благодарен всем откликнувшимся.
0
|
|
| 30.04.2010, 17:02 | |
|
Ответы с готовыми решениями:
40
Написание плагинов для notepad++ Система плагинов Взаимодействие плагинов |
|
22 / 22 / 2
Регистрация: 06.12.2010
Сообщений: 125
|
||||||||||||||||||||||||||
| 12.03.2011, 19:48 | ||||||||||||||||||||||||||
|
эхх... чем пояснять и доказывать, вот вам пример:
Я тут обнаружила потребность народа в некотором примере насчёт использования динамических библиотек. Вот, вытащила из своего проекта куски, относящиеся к загрузке и вызовам. Смысл примера такой: есть приложение, которое грузит (динамически) библиотеки с некоторым интерфейсом (IInterface). Все загружаемые библиотеки наследуют некоторое дефолтное поведение от базового класса (Base). Если библиотека не реализует какой-то метод интерфейса, то будет вызван базовый метод. Это чтобы не переписывать в каждой библиотеке одни и те же действия. Пример загружаемой библиотеки - Derived. Я привела флаги компиляции и сборки для разных систем (я собираю под линюксом с gcc и icc и под вендой с mingw). Вроде ничего не забыла, но возможно, что некоторые флаги не нужны для данного примера (я их поместила в квадратные скобки [...]). Просто у меня проект большой и там много чего ещё кроме этого, поэтому там могли оказаться не относящиеся к данной подзадаче параметры. Да, стандартные флаги для библиотек типа -ldl я сюда не выписывала. Выписаны только специфические параметры. Какие плюсы? Собственно, независимость библиотек от основного кода. Для добавления функционала достаточно перекомпилять загружаемые модули. Базовый функционал класса Base можно менять, не пересобирая библиотеки, которые его используют. Надеюсь, что в принципе понятно. Общий файл интерфейса Interface.h
gcc,icc: CXXFLAGS: -fPIC LDFLAGS: -nodefaultlibs -shared mingw: для венды установить дефайн__DLL (для экспорта) CXXFLAGS: LDFLAGS: -enable-auto-import [-enable-runtime-pseudo-reloc] -Wl,--kill-at Заголовок базового класса Base.h
Инструкции по сборке библиотеки Derived: gcc,icc: CXXFLAGS: -fPIC [-enable-runtime-pseudo-reloc] LDFLAGS: -nodefaultlibs -shared -lBase mingw: для венды установить дефайн __DLL (для экспорта) CXXFLAGS: LDFLAGS: -enable-auto-import [-Wl,--allow-multiple-definition] Заголовок файла основной динамически загружаемой библиотеки Derived.h
gcc,icc: CXXFLAGS: -fPIC LDFLAGS: mingw: CXXFLAGS: LDFLAGS: -enable-auto-import [-enable-runtime-pseudo-reloc] [-Wl,--allow-multiple-definition] -Wl,--kill-at Пример загрузки/выгрузки библиотеки Derived и использования класса (вызов метода init):
меня давно просили и вот количество просьб превысило порог моей лени и я написала своеобразный "отчёт о проделанной работе". перекопав море документации и наступив на кучу граблей, я всё-таки решила свою задачу. не знаю, подойдёт-не подойдёт, но мне кажется, что эти именно то самое, о чём спрашивал niXman или, во всяком случае, очень близкая к этому задача. да, кстати: в С++ классы экспортировать можно. только есть некоторые ограничения. но их можно аккуратненько обойти а внутри одного комплятора (это уже совсем шёпотом) можно даже экспортировать классы без фабрики! просто надо маленько ассемблера добавить и знать чуть-чуть реализацию виртуальных таблиц - и дело в кармане. если очень нужно - могу найти статью, как это делается под вендой. но мне это было не нужно, так как у меня задача как раз - наибольшая переносимость по платформам и компиляторам.
1
|
||||||||||||||||||||||||||
|
|
|
| 13.03.2011, 02:16 [ТС] | |
|
Evg, давайте пойдем с другой стороны.
в моей реализации, что конкретно вы считаете неправильным? и почему? Iron Bug, посмотрел вашу статью. но возник всего один вопрос: что в вашем примере, радикально отличается от моего варианта?! единственное это то, что ваш вариант менее функционален, и сильно хуже спроектирован. или я что-то пропустил? ... подскажите.
0
|
|
|
|
||||||||
| 13.03.2011, 10:24 | ||||||||
0
|
||||||||
|
22 / 22 / 2
Регистрация: 06.12.2010
Сообщений: 125
|
|||
| 13.03.2011, 11:49 | |||
|
Добавлено через 10 минут
0
|
|||
|
|
|
| 13.03.2011, 12:02 | |
|
Iron Bug,
1. Твой код - это обычная реализация виртуального наследования, вынесенного в динамическую библиотеку. 2. В твоём коде нет экспорта типов, потому что на Си++ это невозможно. Ты путаешь понятие экспорта типа и экспорта данных или функций. И твой размышления по части манглирования подтверждают это. 3. Твой код работает только под виндами и линуксом, а потому назвать его кроссплатформенным - несколько оптимистично. Тем более, что даже на две платформы с идеологической точки зрения разведено неправильно. Так же мне с ходу непонятно наличие специфических флагов типа -enable-runtime-pseudo-reloc или -Wl,--allow-multiple-definition, но я под виндой практически не работаю Мне не хотелось бы заниматься подробным обсуждением твоего кода, потому что в данной теме речь идёт совсем о другом. Но твой код, применительно к данной теме - это пример правильной реализации того, как должен выглядеть плагин. Потому что код плагина не выходит за рамки базового интерфейса, предоставленного для работы с плагином. Чего нет в варианте от niXman'а
0
|
|
|
22 / 22 / 2
Регистрация: 06.12.2010
Сообщений: 125
|
||
| 13.03.2011, 12:12 | ||
|
P.S. но в моей реализации там есть "фабрики" - функции для создания и уничтожения представителя класса, реализованные внутри библиотеки. это требуется для совместимости библиотек, собранных разными компиляторами. ибо там выделение памяти разное и прочие различия имеются. сами "фабрики" имеют фиксированные имена и также цепляются через dlsym.
Добавлено через 4 минуты а по части манглирования внутри совместимых на уровне кода (фактически, скомпиленных одним компилятором) библиотек возможна подгрузка куска памяти и инициализация указателей через ассемблер. это и будет чистым "импортом класса". но этот вариант мне не подходит. что касается кроссплатформенности, то мне нужны только линь и венда. по сути, линь - это моя инициатива. а так, всё написано через буст и исключительно стандартные библиотеки. так что если потребуется реализация для мака или ещё чего-то - это будет требовать минимума изменений в коде. софтина сложная и совсем без ifdef'ов тут не обойтись, увы.
0
|
||
|
|
||||
| 13.03.2011, 12:21 | ||||
|
0
|
||||
|
22 / 22 / 2
Регистрация: 06.12.2010
Сообщений: 125
|
||
| 13.03.2011, 12:37 | ||
|
http://www.codeproject.com/KB/... ingLL.aspx это реализация для венды, но под линём тоже можно найти аналогичное решение. ведь загрузчик в этой инфе лазит и её инициализирует. значит, и мы можем это сделать. просто это геморно, архитектурно-зависимо и для моей задачи не подходит. но это работает. если очень усираться, то можно написать такие "загрузчики" для всех систем и архитектур. только нафига оно надо... а про методы именно так и есть. мы должны знать имя. на самом деле, мы можем выкопать его из виртуальной таблицы. но тут включается семантика. ну вот мы выкопали имя, деманглировали (если и это не лень), выковыряли из мангла типы переменных и их количество... а дальше-то что? как это использовать? мы ничего не знаем о семантике метода и его назначении. вот и приплыли.
0
|
||
|
|
||
| 13.03.2011, 17:12 [ТС] | ||
|
вот ты, для того чтоб выделить память, почему используешь функцию malloc() ? вот и мне, для того чтоб использовать функционал предоставляемый плагином реализующим type1, нужно знать интерфейс к type1.
0
|
||
|
|
|||
| 13.03.2011, 17:42 | |||
|
Добавлено через 44 секунды
0
|
|||
|
|
||
| 13.03.2011, 18:03 [ТС] | ||
|
т.е. я работаю на основе информации известной из интерфейса. а из интерфейса я знаю, что у некоторого типа есть некоторые методы. так же знаю, что поведение методов определено не интерфейсом, а его реализацией в плагине. Добавлено через 2 минуты Evg, по моему, мы говорим о разном...
0
|
||
|
|
|||
| 13.03.2011, 18:04 | |||
|
Добавлено через 45 секунд
0
|
|||
|
|
||
| 13.03.2011, 18:08 [ТС] | ||
|
name() description() version() и наследование от этого типа, обязывает реализатора плагина, переопределить эти методы, дабы они возвращали информацию о реализуемом плагине. Добавлено через 1 минуту к примеру, я выкину тип plugin_object, и изменю функцию instance() так, чтоб она возвращала указатель на void. это будет то, о чем говоришь ты?
0
|
||
|
|
|||
| 13.03.2011, 18:18 | |||
|
Iron Bug приводила ссылку со своей реализацией. Вот там всё было правильно: из главной программы не было никаких обращений, выходящих за рамки интерфейса. Вот возьми, к примеру, фотошоп. У него куча всяких фильтров (которые выполняют преобразование изображения). Все они реализованы в виде плагинов и могут добавляться к программе (в том числе и от сторонних разработчиков). Интерфейс плагина, в самом примитивном случае состоит из следующего: - создать экземпляр класса "плагин". Реально создастся экземпляр пронаследованного класса, но он будет отдан программе в виде указателя на базовый класс - выполнить преобразование картинки: в некий метод, определённый в базовом классе, отдаётся картинка на вход и принимается картинка на выходе. Главная программа никоим образом не знает о том, через какой класс всё это реализовано внутри плагина. Знает лишь то, что этот класс является производным классом от базового класса плагина. И главная программа пользуется лишь тем интерфейсом, который описан в базовом классе. Никаких Set и get, который в базовом классе нет
0
|
|||
|
|
|||
| 13.03.2011, 18:36 [ТС] | |||
|
я хочу чтоб плагин type1.so экспортировал функционал согласно интерфейсу type1. поэтому, я получив от плагина инстанс, кастую его к типу type1*, и работаю с указателем на type1. одновременно, я хочу юзать плагин type2.so. так же, получаю инстанс, и кастую его к типу type2*, и работаю с указателем на type2. все. невижу противоречий и нелогичности.
0
|
|||
|
|
|||
| 13.03.2011, 18:47 | |||
|
Я могу реализовать динамическую библиотеку, экспортировать в ней функцию trampampam, в которую передаются два int'а, а она будет возвращать их сумму. Далее могу для вычисления суммы двух чисел подключать эту библиотеку через dlopen и работать через ней. Могу назвать эту библиотеку "плагином". И всё будет работать. За исключением того, что это НЕ будет являться плагином
0
|
|||
|
|
|||
| 13.03.2011, 19:00 [ТС] | |||
|
но мне нужна возможность использовать несколько типов интерфейсов обязывая себя знать, какой плагин, какой интерфейс реализует. детали же реализация плагина мне не известны. это мне и требуется.
0
|
|||
| 13.03.2011, 19:00 | |
|
Как видео с камеры отобразить в браузере без использования сторонних плагинов? Реализовать систему плагинов (модулей), каждый из которых должен работать в отдельном потоке Взаимодействие плагинов с ядром Установка плагинов cppunit + ecut в Eclipse Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу)))
Критические ошибки, мешающие компиляции и. . .
|
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата)
Этот документ предназначен для того, чтобы новый чат Claude мог продолжить
работу без необходимости заново разбираться в. . .
|
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса
Калибровка параметров симбиотической модели: технический обзор
Содержание:
Введение
Постановка проблемы
Технические аспекты реализации
Процесс внедрения изменений
|
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0»
https:/ / ibb. co/ NnkGpfMd
Представленная интегрированная схема описывает непрерывную нелинейную. . .
|
|
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы
### Аннотация
Представлено исследование по разработке агентной модели микоризной. . .
|
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики
Контекст
Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
|
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии
Введение
Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
|
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np
class PlantAgent:
def __init__(self, name, strategy, initial_biomass):
self. name = name
self. strategy = strategy # "greedy" (широколиственные) или. . .
|