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

C++

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

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

30.04.2010, 17:02. Просмотров 23336. Ответов 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
Создание программы кодирования и декодирования файла (любого на выбор преподавателя) кодом Хаффмана. Как сказали нужно оформить в...

40
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
12.03.2011, 14:30  [ТС] #16
Цитата Сообщение от Evg Посмотреть сообщение
Т.е. программа должна "знать" о плагине
она должна знать только интерфесы. ничего более.
0
Evg
Эксперт CАвтор FAQ
18711 / 6680 / 472
Регистрация: 30.03.2009
Сообщений: 18,701
Записей в блоге: 29
12.03.2011, 14:49 #17
Цитата Сообщение от niXman Посмотреть сообщение
она должна знать только интерфесы. ничего более.
Интерфейсом должен служить класс plugin_object, а не type1. Плагин должен обладать тем свойством, что он может быть написан после того, как программа создана, а добавление плагина не должно вызывать перекомпиляцию программы. В твоём случае это не так, т.к. программа использует type1, о котором в момент написания программы не должно быть известно ничего

Добавлено через 55 секунд
Методы Set и Get вываливаются за рамки интерфейса, но ты их используешь в главной программе
0
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
12.03.2011, 14:57  [ТС] #18
мы говорим о разном.

plugin_object - это базовый абстрактный тип. он нужен для того, чтоб обязать кодера переопределить его методы.
plugin_loader::instance() - возвращает указатель на базовый тип. это нужно для того чтоб можно было получить информацию о плагине.
type1 - это и есть реализация, которая определяет поведение плагина. в данном примере, она варит плюшки. так же, в приложение я могу добавить плагин который будет жарить пельмени.

тут главное, что при помощи plugin_loader::instance() я получаю указатель на базовый тип, и могу его кастовать к нужному, именно потому, что плагин и его лоадер ничего не знают о внутренней реализации.

Добавлено через 55 секунд
другими словами: это типичный динамический полиморфизм.
0
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
12.03.2011, 15:44 #19
видимо, надо мне взять и написать howto по теме экспорта-импорта.
у меня реализована софтина, которая тащит функции из подгружаемых динамически (через dlopen и LoadLibrary, софтина кроссплатформенная) библиотек. причём кроме простого подтаскивания там ещё реализован механизм наследования всех "плагинов" от одной общей динамической библиотеки, в которой сосредоточено "дефолтное" поведение классов.
всё это работает, но настроек дофига и мне нужно собраться и просто взять и написать, что и как.
а так, если это С++, то классы экспортировать можно. есть некоторые проблемы с экспортом-импортом классов между разными компиляторами(и, увы, они неразрешимы). но если планируется, что юзеры будут использовать совместимые на уровне name mangling компиляторы (например, семейство gcc и icc), то можно не париться и смело экспортировать классы. разница только в этом.
тем не менее, даже в случае разных компиляторов классы можно использовать: создать в библиотеке фабрику для создания представителя класса и возвращать указатель на готовый объект. только уничтожаться он также должен в библиотеке. я просто делаю две функции: создать элемент класса и уничтожить его и через вызовы получаю указатель и работаю с ним.
собственно, если есть конкретные вопросы, я могу поковырять код и сказать, что к чему. у меня была мысль сделать небольшую статью на эту тему, про грабли и варианты их обхода, но пока просто не хватает времени, ибо пишу огромный и сложный проект.
0
Evg
Эксперт CАвтор FAQ
18711 / 6680 / 472
Регистрация: 30.03.2009
Сообщений: 18,701
Записей в блоге: 29
12.03.2011, 16:32 #20
Цитата Сообщение от niXman Посмотреть сообщение
при помощи plugin_loader::instance() я получаю указатель на базовый тип, и могу его кастовать к нужному
К какому нужному? main - это твоя программа. В момент её написания плагина ещё нет, а следовательно, типа type1 тоже нет. Как ты напишешь программу с использованием несуществующего типа?

Добавлено через 2 минуты
Iron Bug, тут немного не то. Человека заклинило на мысли, что нужно экспортировать класс, а не методы класса (что есть на самом деле функции). Ну нельзя в Си++ экспортировать тип в нормальном понимании этого слова. Теоретически это сделать можно, но это будет не тип языка Си++, а тип некоего виртуального интерпретатора, который будет включен в компилятор

Добавлено через 3 минуты
niXman, пойми ты простую вещь: плагин должен подключаться к программе без перекомпиляции этой самой программы. В противном случае это не плагин, а обычный кусок программы, реализованный в виде динамической библиотеки
0
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
12.03.2011, 19:48 #21
эхх... чем пояснять и доказывать, вот вам пример:
Я тут обнаружила потребность народа в некотором примере насчёт использования динамических библиотек.
Вот, вытащила из своего проекта куски, относящиеся к загрузке и вызовам.
Смысл примера такой: есть приложение, которое грузит (динамически) библиотеки с некоторым интерфейсом (IInterface).
Все загружаемые библиотеки наследуют некоторое дефолтное поведение от базового класса (Base). Если библиотека не реализует какой-то метод интерфейса, то будет вызван базовый метод. Это чтобы не переписывать в каждой библиотеке одни и те же действия.
Пример загружаемой библиотеки - Derived.
Я привела флаги компиляции и сборки для разных систем (я собираю под линюксом с gcc и icc и под вендой с mingw).
Вроде ничего не забыла, но возможно, что некоторые флаги не нужны для данного примера (я их поместила в квадратные скобки [...]). Просто у меня проект большой и там много чего ещё кроме этого, поэтому там могли оказаться не относящиеся к данной подзадаче параметры. Да, стандартные флаги для библиотек типа -ldl я сюда не выписывала. Выписаны только специфические параметры.
Какие плюсы? Собственно, независимость библиотек от основного кода. Для добавления функционала достаточно перекомпилять загружаемые модули. Базовый функционал класса Base можно менять, не пересобирая библиотеки, которые его используют.

Надеюсь, что в принципе понятно.

Общий файл интерфейса Interface.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
 
// interface
class IInterface
{
public:
    IInterface() {};
    virtual ~IInterface() {};
    virtual void init() = 0;
};
 
// types for class instance creators/destroyers 
typedef IInterface *(*funcInterfaceCreate_type)();
typedef void (*funcInterfaceDelete_type)(IInterface *);
 
#endif // __INTERFACE_H__
Инструкции по сборке базовой библиотеки Base:
gcc,icc:
CXXFLAGS: -fPIC
LDFLAGS: -nodefaultlibs -shared

mingw:
для венды установить дефайн__DLL (для экспорта)
CXXFLAGS:
LDFLAGS: -enable-auto-import [-enable-runtime-pseudo-reloc] -Wl,--kill-at

Заголовок базового класса Base.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef __BASE_H__
#define __BASE_H__
 
#include "Interface.h"
 
#ifndef __linux__
#ifdef __DLL
#define __BASE_DLL __declspec(dllexport)
#else
#define __BASE_DLL __declspec(dllimport)
#endif
#else
#define __BASE_DLL
#endif
 
class __BASE_DLL Base : public IInterface
{
protected:
    int _param;
public:
    Base();
    virtual ~Base();
    virtual void init();
};
 
#endif
Base.cpp не привожу, он тут не важен. Там можно что-то выполнять, какие-то базовые действия.

Инструкции по сборке библиотеки 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
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef __DERIVED_H__
#define __DERIVED_H__
 
#include "Base.h" 
 
#ifndef __linux__
#ifdef __DLL
    #define __DERIVED_DLL __declspec(dllexport)
#else
    #define __DERIVED_DLL __declspec(dllimport)
#endif
#else
#define __DERIVED_DLL
#endif
 
class __DERIVED_DLL Derived : public Base
{
    public:
        Derived();
        virtual ~Derived();
        virtual void init();
};
#endif
Пример реализации основной динамически загружаемой библиотеки Derived.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "Derived.h"
 
Derived::Derived() : Base()
{}
 
Derived::~Derived()
{}
 
void Derived::init()
{
    Base::init();
}
 
#ifdef __cplusplus
extern "C" {
#endif
 
IInterface
#ifndef __linux__
__stdcall __DERIVED_DLL
#endif
*CreateObject()
{
    return (IInterface*)new Derived();
}
 
void
#ifndef __linux__
__stdcall __DERIVED_DLL
#endif
DeleteObject(IInterface *pDerived)
{
    if(pDerived==0) throw;
    delete(pDerived);
}
 
#ifdef __cplusplus
}
#endif
Инструкции по сборке вызывающей программы:
gcc,icc:
CXXFLAGS: -fPIC
LDFLAGS:

mingw:
CXXFLAGS:
LDFLAGS: -enable-auto-import [-enable-runtime-pseudo-reloc] [-Wl,--allow-multiple-definition] -Wl,--kill-at

Пример загрузки/выгрузки библиотеки Derived и использования класса (вызов метода init):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "IInteface.h"
 
#ifdef __linux__
void *_pDll; // linux handle for dynamic library
#else
HMODULE _hDll; // windows handle for dynamic library
#endif
 
funcInterfaceCreate_type _pFuncCreateObject; //pointer to CreateObject function in dll
funcInterfaceDelete_type _pFuncDeleteObject; //pointer to DeleteObject function in dll
 
IInterface *_pInterface;
 
void load()
{
#ifdef __linux__
    _pDll = dlopen("libDerived.so",RTLD_NOW);
    if(_pDll != 0)
    {
        union
        {
            funcInterfaceCreate_type func;
            void *ptr;
        } uniCreate;
        uniCreate.ptr = dlsym(_pDll,"CreateObject");
        _pFuncCreateObject = uniCreate.func;
        union
        {
            funcInterfaceDelete_type func;
            void *ptr;
        } uniDelete;
        uniDelete.ptr = dlsym(_pDll,"DeleteObject");
        _pFuncDeleteObject = uniDelete.func;
    }
#else
    _hDll = LoadLibrary("Derived.dll");
    if(_hDll != NULL)
    {
        _pFuncCreateObject = (funcInterfaceCreate_type)GetProcAddress(_hDll,"CreateObject");
        _pFuncDeleteObject = (funcInterfaceDelete_type)GetProcAddress(_hDll,"DeleteObject");
    }
#endif
    _pInterface = (*_pFuncCreateObject)();
}
 
void unload()
{
    (*_pFuncDeleteObject)(_pInterface);
 
#ifdef __linux__
    dlclose(_pDll);
#else
    FreeLibrary(_hDll);
#endif
}
 
void use()
{
    _pInterface->init();
}
Примечание: при вызове _pInterface->init() будет вызван метод init класса Derived.


меня давно просили и вот количество просьб превысило порог моей лени и я написала своеобразный "отчёт о проделанной работе". перекопав море документации и наступив на кучу граблей, я всё-таки решила свою задачу. не знаю, подойдёт-не подойдёт, но мне кажется, что эти именно то самое, о чём спрашивал niXman или, во всяком случае, очень близкая к этому задача.

да, кстати: в С++ классы экспортировать можно. только есть некоторые ограничения. но их можно аккуратненько обойти а внутри одного комплятора (это уже совсем шёпотом) можно даже экспортировать классы без фабрики! просто надо маленько ассемблера добавить и знать чуть-чуть реализацию виртуальных таблиц - и дело в кармане. если очень нужно - могу найти статью, как это делается под вендой. но мне это было не нужно, так как у меня задача как раз - наибольшая переносимость по платформам и компиляторам.
1
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
13.03.2011, 02:16  [ТС] #22
Evg, давайте пойдем с другой стороны.
в моей реализации, что конкретно вы считаете неправильным? и почему?

Iron Bug, посмотрел вашу статью. но возник всего один вопрос: что в вашем примере, радикально отличается от моего варианта?! единственное это то, что ваш вариант менее функционален, и сильно хуже спроектирован.
или я что-то пропустил? ... подскажите.
0
Evg
Эксперт CАвтор FAQ
18711 / 6680 / 472
Регистрация: 30.03.2009
Сообщений: 18,701
Записей в блоге: 29
13.03.2011, 10:24 #23
Цитата Сообщение от Iron Bug Посмотреть сообщение
в С++ классы экспортировать можно
Да не экспортируешь их ты. В том понимании, что подразумевается под этим словом в отношении плагинов. Не надо путать понятие экспорта по отношению к библиотеке (когда требуется компиляция программы) и экспорта по отношению к плагину (когда программу перекомпилировать не надо)

Цитата Сообщение от niXman Посмотреть сообщение
Evg, давайте пойдем с другой стороны.
в моей реализации, что конкретно вы считаете неправильным? и почему?
Я уже несколько раз объяснил про одно и то же. По твоей теории я могу написать вот такой "плагин":

C++
1
2
3
4
5
6
7
8
9
10
11
12
struct type_evg: plugin_object {
   type_evg();
   virtual const char* name() const;
   virtual const char* description() const;
   virtual const char* version() const;
   
   virtual void set_evg(int);
   virtual int get_evg() const { return 44; }
   
private:
   int val;
};
Вот теперь скажи мне, как ты заставишь свою программу вызвать метод set_evg?
0
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
13.03.2011, 11:49 #24
Цитата Сообщение от niXman Посмотреть сообщение
Iron Bug, посмотрел вашу статью. но возник всего один вопрос: что в вашем примере, радикально отличается от моего варианта?! единственное это то, что ваш вариант менее функционален, и сильно хуже спроектирован.
или я что-то пропустил? ... подскажите.
это просто кроссплатформенная реализация того, что мне было нужно. с примером, как это собирать. не более. для моей задачи функциональность вполне достаточна и главное: это работает. это не теория, это практика.

Добавлено через 10 минут
Цитата Сообщение от Evg Посмотреть сообщение
Да не экспортируешь их ты. В том понимании, что подразумевается под этим словом в отношении плагинов. Не надо путать понятие экспорта по отношению к библиотеке (когда требуется компиляция программы) и экспорта по отношению к плагину (когда программу перекомпилировать не надо)
вот в моём примере как раз и не надо. просто у меня не плагины, а библиотеки для работы с разными железяками, т.к. я хардварный программист, но не суть. смысл в том, что вызывающей программе не требуется знать ничего, кроме интерфейса. она через него вызывает виртуальные методы и это работает. и дополнительно классы "плагинов" наследуются от базового класса, который сидит в ещё одной библиотеке. таким образом реализовано дефолтное поведение: т.е. если "плагин" не реализовал какой-то метод интерфейса, то будет взят метод из базового класса. базовый класс прицеплен к программе через линковку(но не суть, на самом деле, можно его и через dlopen тащить, просто не требуется), остальное всё грузится динамически через dlopen и оно работает. под разными системами. вызываются перегруженные вирутальные методы интерфейса и т.п. никакой перекомпиляции программы не нужно, ибо она знает только о заголовочнике интрерфейса.
0
Evg
Эксперт CАвтор FAQ
18711 / 6680 / 472
Регистрация: 30.03.2009
Сообщений: 18,701
Записей в блоге: 29
13.03.2011, 12:02 #25
Iron Bug,

1. Твой код - это обычная реализация виртуального наследования, вынесенного в динамическую библиотеку.
2. В твоём коде нет экспорта типов, потому что на Си++ это невозможно. Ты путаешь понятие экспорта типа и экспорта данных или функций. И твой размышления по части манглирования подтверждают это.
3. Твой код работает только под виндами и линуксом, а потому назвать его кроссплатформенным - несколько оптимистично. Тем более, что даже на две платформы с идеологической точки зрения разведено неправильно. Так же мне с ходу непонятно наличие специфических флагов типа -enable-runtime-pseudo-reloc или -Wl,--allow-multiple-definition, но я под виндой практически не работаю

Мне не хотелось бы заниматься подробным обсуждением твоего кода, потому что в данной теме речь идёт совсем о другом. Но твой код, применительно к данной теме - это пример правильной реализации того, как должен выглядеть плагин. Потому что код плагина не выходит за рамки базового интерфейса, предоставленного для работы с плагином. Чего нет в варианте от niXman'а
0
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
13.03.2011, 12:12 #26
P.S. но в моей реализации там есть "фабрики" - функции для создания и уничтожения представителя класса, реализованные внутри библиотеки. это требуется для совместимости библиотек, собранных разными компиляторами. ибо там выделение памяти разное и прочие различия имеются. сами "фабрики" имеют фиксированные имена и также цепляются через dlsym.

Добавлено через 4 минуты
Цитата Сообщение от Evg Посмотреть сообщение
В твоём коде нет экспорта типов, потому что на Си++ это невозможно. Ты путаешь понятие экспорта типа и экспорта данных или функций. И твой размышления по части манглирования подтверждают это.
другой реализации "экспорта класса", кроме экспорта его данных, создать просто нельзя. ибо разные компиляторы создают разные физические реализации объекта. поэтому мой метод - единственно возможный для использования перегруженных методов из динамических библиотек, собственно.
а по части манглирования внутри совместимых на уровне кода (фактически, скомпиленных одним компилятором) библиотек возможна подгрузка куска памяти и инициализация указателей через ассемблер. это и будет чистым "импортом класса". но этот вариант мне не подходит.
что касается кроссплатформенности, то мне нужны только линь и венда. по сути, линь - это моя инициатива. а так, всё написано через буст и исключительно стандартные библиотеки. так что если потребуется реализация для мака или ещё чего-то - это будет требовать минимума изменений в коде. софтина сложная и совсем без ifdef'ов тут не обойтись, увы.
0
Evg
Эксперт CАвтор FAQ
18711 / 6680 / 472
Регистрация: 30.03.2009
Сообщений: 18,701
Записей в блоге: 29
13.03.2011, 12:21 #27
Цитата Сообщение от Iron Bug Посмотреть сообщение
P.S. но в моей реализации там есть "фабрики" - функции для создания и уничтожения представителя класса, реализованные внутри библиотеки. это требуется для совместимости библиотек, собранных разными компиляторами. ибо там выделение памяти разное и прочие различия имеются. сами "фабрики" имеют фиксированные имена и также цепляются через dlsym
Скажем так, чтобы уметь запустить функцию из подгруженной в run-time динамической библиотеки, нужно уметь как-то найти эту функцию. Единственный для этого способ - это по символьному имени функции. Надёжным образом это можно сделать только для тех функций (и переменных), имена которых НЕ подвергаются манглированию со стороны компилятора. Таким свойством обладают только функции (и переменные), реализованные на Си (или на Си++ внутри блока extern "C"). Поэтому такая "фабрика" - это единственный способ вызвать создание объекта извне библиотеки

Цитата Сообщение от Iron Bug Посмотреть сообщение
другой реализации "экспорта класса", кроме экспорта его данных, создать просто нельзя. ибо разные компиляторы создают разные физические реализации объекта
Не только поэтому. В языках Си и Си++ попросту нет возможности работать с динамически созданными типами. Любой тип, с которым идёт работа, должен быть виден в момент компиляции.

Цитата Сообщение от Iron Bug Посмотреть сообщение
поэтому мой метод - единственно возможный для использования перегруженных методов из динамических библиотек, собственно.
Именно так. А способов вызвать "новый" метод (т.е. не описанный в базовом классе), коими являются set и get в варианте niXman'а, попросту нет. В цитате слово "метод" выделил жирным - лучше в таком контексте использовать слово "способ", чтобы не путать с методами языка Си++
0
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
13.03.2011, 12:37 #28
Цитата Сообщение от Evg Посмотреть сообщение
Поэтому такая "фабрика" - это единственный способ вызвать создание объекта извне библиотеки
я уже десятый раз повторяю, что не единственный. я наконец-то нашла линк на ассемблерные приколы с библиотеками:
http://www.codeproject.com/KB/DLL/classesexportedusingLL.aspx
это реализация для венды, но под линём тоже можно найти аналогичное решение. ведь загрузчик в этой инфе лазит и её инициализирует. значит, и мы можем это сделать. просто это геморно, архитектурно-зависимо и для моей задачи не подходит. но это работает. если очень усираться, то можно написать такие "загрузчики" для всех систем и архитектур. только нафига оно надо...
а про методы именно так и есть. мы должны знать имя. на самом деле, мы можем выкопать его из виртуальной таблицы. но тут включается семантика. ну вот мы выкопали имя, деманглировали (если и это не лень), выковыряли из мангла типы переменных и их количество... а дальше-то что? как это использовать? мы ничего не знаем о семантике метода и его назначении. вот и приплыли.
0
Evg
Эксперт CАвтор FAQ
18711 / 6680 / 472
Регистрация: 30.03.2009
Сообщений: 18,701
Записей в блоге: 29
13.03.2011, 14:12 #29
Цитата Сообщение от Iron Bug Посмотреть сообщение
я уже десятый раз повторяю, что не единственный
Говоря про "способ" я имею в виду человеческие способы. То, что тут написано - это черезж...ное решение для извращенцев, коих я тебе могу выдать миллион.
0
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
13.03.2011, 16:52  [ТС] #30
Цитата Сообщение от Evg Посмотреть сообщение
как ты заставишь свою программу вызвать метод set_evg?
никак.
если программа не знает интерфейса, значит ей вовсе этот плагин не нужен, т.к. невозможно работать с неизвестным типом.
0
13.03.2011, 16:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2011, 16:52
Привет! Вот еще темы с ответами:

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'ы.


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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