Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 185, средняя оценка - 4.83
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
#1

Теория плагинов - C++

30.04.2010, 17:02. Просмотров 22935. Ответов 40
Метки нет (Все метки)

Всем привет.
Для одной моей проги, нужно реализовать поддержку плагинов.
Плагины предполагаются простенькие, написанные на Си.

То, что плагин, это просто .so файл - понятно.
То, что прога может дергать из .so файла функции - тоже понятно.

1. Непонятно то, как сам плагин сможет дергать функции из программы?
2. Программа написана на С++, но плагины предполагаю писать на Си, во избежания бинарной несовместимости. В этом случае, какие сложности могут возникнуть?
3. Еще непонятно, каким образом "разделять" плагины, ведь их может быть несколько?
4. И еще непонятно, каким образом программе "сообщить" какие функции дергать из конкретного плагина?
5. И еще непонятно, каким образом плагин, сможет дергать функции из другого плагина?

Нужна теоретическая подкова

Благодарен всем откликнувшимся.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2010, 17:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Теория плагинов (C++):

Написание плагинов для notepad++ - C++
Добрый день! Есть задача написания плагина для notepad++ - немного модифицировать его графический интерфейс. Ранее плагины писать не...

Г.Шилдт. Теория и практика С++ - C++
Кто-нибудь дайте бесплатную ссылку на книгу: Г.Шилдт. Теория и практика С++. BHV-Санкт-Петербург. 416 стр Please, очень...

Теория оптимизации - C++ Builder
Доброго! В интернете натолкнулся на статью бывалого прогера, который говорит несколько простых правил оптимизации кода Си. Делал опыты по...

Теория автоматов - C++ Builder
Народ, подскажите как сделать вот задачку: V=(a,b,c). Автомат распознает все строки в которой две послдение буквы не совпадают.

комбинаторика и теория вероятности - C++ Builder
Помогите, пожалуйста, решить задачу! Задача: Имитировать перетасовку новой колоды игральных карт в 52 листа многократным применением...

Теория Информации. Код ХАФФМАНА - C++ Builder
Создание программы кодирования и декодирования файла (любого на выбор преподавателя) кодом Хаффмана. Как сказали нужно оформить в...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Evg
Эксперт CАвтор FAQ
17819 / 6029 / 388
Регистрация: 30.03.2009
Сообщений: 16,559
Записей в блоге: 26
01.05.2010, 00:56 #2
Цитата Сообщение от niXman Посмотреть сообщение
1. Непонятно то, как сам плагин сможет дергать функции из программы?
Элементарно по имени. Если программа гарантирует, к примеру, что в программе есть функция func1, то в плагине можно написать extern-описание и дёргать по имени. Если плагин на Си, а программа на Си++, то в программе функция должна быть описана как extern "C". Можно в плагин подсовывать указатели на функции.

Цитата Сообщение от niXman Посмотреть сообщение
2. Программа написана на С++, но плагины предполагаю писать на Си, во избежания бинарной несовместимости. В этом случае, какие сложности могут возникнуть?
Принципиальных - нет. Понятно, что общение между программой и плагином будет в терминах языках Си - никаких классов и прочей лабудени.

Цитата Сообщение от niXman Посмотреть сообщение
3. Еще непонятно, каким образом "разделять" плагины, ведь их может быть несколько?
plugin1.so, plugin2.so
Или я не понял вопроса

Цитата Сообщение от niXman Посмотреть сообщение
4. И еще непонятно, каким образом программе "сообщить" какие функции дергать из конкретного плагина?
Варианты бывают разные, но в любом случае плагин пишется не от балды, а согласно некоторому зафиксированному интерфейсу. Например, возможен такой вариант, что плагин обязан иметь функции func1, func2 с такими-то интерфейсами и переменные var1, var2 таких-то типов

Цитата Сообщение от niXman Посмотреть сообщение
5. И еще непонятно, каким образом плагин, сможет дергать функции из другого плагина?
Можно точно так же - по имени. Но это слишком замудрёно (например, тогда один плагин не сможет работать без другого). Более правильный вариант - это когда главная программа является посредником, добывает из первого плагина указатель на функцию и отдаёт его во второй плагин.
1
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
01.05.2010, 03:01  [ТС] #3
Цитата Сообщение от Evg Посмотреть сообщение
Элементарно по имени.
так эти функции должны быть экспортируемые из программы? что-то не понимаю..

Цитата Сообщение от Evg Посмотреть сообщение
plugin1.so, plugin2.so
и вправду, все гениальное просто

Цитата Сообщение от Evg Посмотреть сообщение
Или я не понял вопроса
допустим, программа экспортирует некую функцию, которая для определенных плагинов, ведет себя по особенному.

Цитата Сообщение от Evg Посмотреть сообщение
Варианты бывают разные, но в любом случае плагин пишется не от балды, а согласно некоторому зафиксированному интерфейсу. Например, возможен такой вариант, что плагин обязан иметь функции func1, func2 с такими-то интерфейсами и переменные var1, var2 таких-то типов
тут понятно.

Цитата Сообщение от Evg Посмотреть сообщение
Можно точно так же - по имени. Но это слишком замудрёно (например, тогда один плагин не сможет работать без другого). Более правильный вариант - это когда главная программа является посредником, добывает из первого плагина указатель на функцию и отдаёт его во второй плагин.
теория понятна. в реализации не очень.. буду спрашивать по ходу..
0
Evg
Эксперт CАвтор FAQ
17819 / 6029 / 388
Регистрация: 30.03.2009
Сообщений: 16,559
Записей в блоге: 26
01.05.2010, 11:06 #4
Цитата Сообщение от niXman Посмотреть сообщение
так эти функции должны быть экспортируемые из программы? что-то не понимаю..
Понятия типа "экспортирует", "импортирует" скорее характерны для языков типа паскаля или оберона, но условно можно сказать, что так

Цитата Сообщение от niXman Посмотреть сообщение
допустим, программа экспортирует некую функцию, которая для определенных плагинов, ведет себя по особенному.
Функция всегда ведёт себя одинаково, наличие плагина не должно влиять на работу

Ты лучше поясни конкретно, что хочешь
1
Vourhey
Почетный модератор
6481 / 2256 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
01.05.2010, 12:20 #5
niXman, если у тебя какая-то функция в определенных плагинах ведет себя совсем "по-особенному", то лучше будет разделить твои плагины по типу. К примеру, чтобы любой твой плагин экспортировал функцию, допустим, getType(), которая вернет тип плагина. Это может быть число или строчка, как угодно. Твоя основная программа будет всегда будет вызывать эту функцию после загрузки .so и определять с каким типом плагина она имеет дело и соответстенно знать, что в общих чертах будут делать функции этого плагина.
Или я не понял вопрос
1
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
10.03.2011, 16:41  [ТС] #6
а как экспортировать классы из плагина?
к примеру, мне нужно, чтоб некоторый плагин определял реализацию некоторого класса. при этом, программа, знает экспортируемый тип только по интерфейсу. тогда, полагаю, в плагине должна быть функция типа create()

пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// интерфейс.
class i_type {
   i_type(int);
   ~i_type();
 
   virtual int get() const = 0;
   virtual int add(int) = 0;
};
 
// реализация для типа в плагине
class type: public i_type {
   type(int v):i_type(v) {}
   virtual ~type() {}
 
   virtual int get() const { return 3; }
   virtual int add(int v) { return 3+v; }
};
 
// функция плагина создающая объект
i_type* create(int v) {
   return new type(v);
}
какие в этом случае меня ожидают проблемы, возможно в будущем?
как все же экспортировать классы из плагина?

спасибо.
0
Evg
Эксперт CАвтор FAQ
17819 / 6029 / 388
Регистрация: 30.03.2009
Сообщений: 16,559
Записей в блоге: 26
10.03.2011, 17:24 #7
Вообще говоря, классы нельзя "экспортировать". В Си++ компилятор должен явно видеть описание класса. Можно конечно мухлевать с виртуальными классами, но так или иначе у тебя будут экспортироваться действия или данные, но не типы
1
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
10.03.2011, 17:47  [ТС] #8
т.е. приведенный мною код, не жизнеспособен?
0
Evg
Эксперт CАвтор FAQ
17819 / 6029 / 388
Регистрация: 30.03.2009
Сообщений: 16,559
Записей в блоге: 26
10.03.2011, 18:00 #9
Жизнеспособность кода зависит от того, что ты вкладываешь в это понятие. Ты же по сути не экспортируешь новые типы, а экспортируешь лишь указатель на объект, приведённый к базовому типу. Основная программа может через этот указатель вызывать методы класса i_type, но фактически это означает лишь работу с кодами и с данными. Но не с типом.

Это вовсе не есть экспортирование производного типа, а всего лишь обычное виртуальное наследование.
1
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
10.03.2011, 18:13  [ТС] #10
Цитата Сообщение от Evg Посмотреть сообщение
зависит от того, что ты вкладываешь в это понятие.
эм... что он должен работать

Цитата Сообщение от Evg Посмотреть сообщение
Ты же по сути не экспортируешь новые типы, а экспортируешь лишь указатель на объект, приведённый к базовому типу.
этот способ я надумал после того, как ты сказал что классы нельзя экспортировать.

Цитата Сообщение от Evg Посмотреть сообщение
Основная программа может через этот указатель вызывать методы класса i_type, но фактически это означает лишь работу с кодами и с данными. Но не с типом.
поясни, что имеется ввиду?

Цитата Сообщение от Evg Посмотреть сообщение
Это вовсе не есть экспортирование производного типа, а всего лишь обычное виртуальное наследование.
ок.
а как реализовать экспортирование? или это все же никоим образом невозможно?
0
Evg
Эксперт CАвтор FAQ
17819 / 6029 / 388
Регистрация: 30.03.2009
Сообщений: 16,559
Записей в блоге: 26
10.03.2011, 18:30 #11
Цитата Сообщение от niXman Посмотреть сообщение
поясни, что имеется ввиду?
Основная программа видит лишь указатель на type_i, и она не может сделать чего-то большего, чем описано в этом классе (о котором программа и так знает). Т.е. для программы нового типа не появилось.

Цитата Сообщение от niXman Посмотреть сообщение
а как реализовать экспортирование? или это все же никоим образом невозможно?
Заводишь какую-нибудь структуру, в котором как-то писываешь тип (да хоть в текстововм виде). Описываешь какие-то ацкие функции для работы с таким описанием типа. Фактически пишешь интерпретатор. Собственно - по другому тип и никак нельзя экспортировать. Те языки, которые имеют такую возможность, так или иначе реализованы через что-то наподобие интерпретатора, который включен в динамическую поддержку языка. (и таким образом всем этим занимаются разработчики комплятора, а не пользователи)
1
g_u_e_s_t
1258 / 649 / 30
Регистрация: 06.02.2011
Сообщений: 1,724
10.03.2011, 18:33 #12
Не очень вникал в трид, но предложу такое:
C++
1
2
3
4
5
6
7
8
9
10
11
#define EXPORT __attribute__((visibility("default")))
 
class EXPORT myclass{
public:
myclass(...);
 
virtual int mymethod();
int p;
};
 
typedef myclass* myclass_t(...);
1
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
10.03.2011, 18:46  [ТС] #13
Добавлено через 1 минуту
Evg, и последний вопрос: можешь пояснить более популярно чем в куче манов, что конкретно выполняет флаг -fPIC при либковке .so файла?

обсуждение продолжено здесь: Вопросы по динамическим библиотекам
0
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
12.03.2011, 13:46  [ТС] #14
есть базовый тип для плагинов:
C++
1
2
3
4
5
struct plugin_object {
   virtual const char* name() const = 0;
   virtual const char* description() const { return "null"; }
   virtual const char* version() const { return "null"; }
};
далее я наследуюсь от него и реализую собственный тип.
C++
1
2
3
4
5
6
7
8
9
10
11
12
struct type1: plugin_object {
   type1();
   virtual const char* name() const;
   virtual const char* description() const;
   virtual const char* version() const;
   
   void set(int);
   int get() const;
   
private:
   int val;
};
реализация в .cpp фале. ее приводить не буду. ничего интересного в ней нет.

собираю плагин так:
> g++ -fPIC -c test.cpp
> g++ -shared test.o -o test.so
тестовое приложение выглядит так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(int argc, char** argv) {
   plugin_loader plugin("test.so");
   plugin_object* obj = plugin.instance();
 
   std::cout
   << "name: " << obj->name() << std::endl
   << "description: " << obj->description() << std::endl
   << "version: " << obj->version() << std::endl;
 
   type1* t1 = static_cast<type1*>(obj);
   int v = t1->get();
   std::cout << "v = " << v << std::endl;
   t1->set(33);
   v = t1->get();
   std::cout << "v = " << v << std::endl;
}
при линковке получаю это:
undefined reference to `type1::get() const'
undefined reference to `type1::set(int)'
undefined reference to `type1::get() const'
оно и понятно, еще несколько моментов необходимо знать:
1) методы реализаций должны быть виртуальными.
т.е. в наши методы get() и set() нужно добавить спецификатор virtual.

2) в хидере, не пишите реализацию, т.к. в таком случае, компилятор будет использовать ее, и получится каша
пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
struct type1: plugin_object {
   type1();
   virtual const char* name() const;
   virtual const char* description() const;
   virtual const char* version() const;
   
   virtual void set(int);
   virtual int get() const { return 44; }
   
private:
   int val;
};
при вызове метода get() из тестового приложения, вы вне зависимости от реализации в .so файле, получите как результат 44
0
Evg
Эксперт CАвтор FAQ
17819 / 6029 / 388
Регистрация: 30.03.2009
Сообщений: 16,559
Записей в блоге: 26
12.03.2011, 14:19 #15
В твоём примере главная программа использует тип type1, который реализован в плагине. Т.е. программа должна "знать" о плагине, что, мягко говоря, делает твой плагин не плагином, а частью программы
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.03.2011, 14:19
Привет! Вот еще темы с ответами:

Dynamic-Link Library: Теория + Практика - C++ Builder
1. Теоретическая часть. Знакомство с Dynamic-Link Library. 1.1. Что такое DLL. 1.2. Использование DLL. 1.3. Необходимость...

Теория защиты презентации (ppt и pptx) - C++ Builder
Добрый день! Озадачили меня на работе написать простую защиту презентаций, выполненных в программе Microsoft PowerPoint. ...

1C 8.x Теория плагинов - 1С
Гуру, обьясните кто сталкивался... Есть плагин на Делфи в виде dll под 1С77 с исходниками. Я сам писал... запись и чтение текстовых...

Теория создания плагинов. - Visual Basic
Нужна информация о создании программ к которым в процессе работы можно было бы подключать plug-in'ы.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
12.03.2011, 14:19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru