crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Неопределенные классы в динамической библиотеке
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Flex Ferrum Дата 5.11.2014, 16:12
  (зашёл сюда по приглашению ViGOur'а)
Мне видится такой вариант ответа на поставленный в первом посте вопрос - скомбинировать compiletime-анализ в runtime.
Со стороны плагина делается следующее:
1. Для плагина делается небольшой шаблонный фреймворк, основная задача которого - принять сигнатуру тестируемой функции, констрейнты на аргументы и превратить это в универсальный invoke-ер. При этом фреймворк (используя typeinfo и typename для сигнатуры функции и для каждого аргумента) формирует набор структур, которые однозначно и с необходимой детализацией эту функцию описывают. В общем итоге плагин передаёт приложению следующую информацию:
- Полученные на этапе компиляции структуры, описывающие типы аргументов функции и констрейнты на них;
- Указатель на функцию-invoker (с точно заданной сигнатурой), которая получает на массив аргументов и передаёт их в тестируемую функцию.
2. Со стороны приложения делается runtime-анализатор данных, полученных от плагина. На основании этих данных строится GUI, прописываются валидаторы аргументов и т. д. Когда пользователь нажимает на кнопку "test" (или как она там будет называться), то введённые им аргументы превращаются в массив структур, и этот массив передаётся в invoke-ер. Там все элементы этого массива превращаются в аргументы тестируемой функции и делается собственно вызов.
Для добавления type safety можно использовать boost::variant для передачи значений аргументов (ведь GUI будет работать с конечным набором типов).
ViGOur Дата 5.11.2014, 14:34
  Блин, блинский, это то у меня совсем из головы-то и вылетело!
Беру тайм-аут на подумать...
Iron Bug Дата 5.11.2014, 13:55
  ну да. только без темплейтов получится монстр. потому что обработка разных типов параметров займёт туеву хучу кода. обработка совершенно одинакова для всех типов, но темплейты в случае с библиотеками не работают. нельзя экспортировать классы с шаблонами.
ViGOur Дата 5.11.2014, 13:15
  не обязательно, можно так же передавать указатель на структуру, в которой будут перечисленны параметры...
А лучше как я уже говорил, в указателе на класс! А в классе уже сделать стандартная реализация получения функции алгоритма, и параметром с их описанием! ;)
В предложенном мной варианте, как раз все просто!
Iron Bug Дата 5.11.2014, 13:04
  GUI тут вообще ни при чём. я так понимаю, что это обычный софт для тестирования работы алгоритмов.
надо не только создать некий объект с алгоритмом, но и вызывать его, с переменными параметрами. а вот тут-то и происходит затык.
короче говоря, это вызов функции по указателю, с передачей заранее неизвестного числа аргументов. с dll это не проканает. тут надо городить какой-то огород со специальными методами передачи параметров, чтобы унифицировать вызовы.
ViGOur Дата 5.11.2014, 12:18
  Тут мне кажется немного не правильный подход.
Зачем заморачиваться на функциях, когда библиотека может отдавать указатель на класс нужного в данный момент алгоритма, на основе которого будет строится GUI для данного алгоритма и отрабатывать сам алгоритм?
Причем класс может быть как стандартным (для ленивых), который работает с нужной функцией, так и расширенным пользователем (с описанием параметров и ...).

Другими словами, мы задаем некие правила, которым должны следовать пользователи, и в данном случае нам нужно будет давать пользователям только базовый класс CAlgorithmBase с правилами его использования и все...
Iron Bug Дата 5.11.2014, 11:14
  ViGOur, тут вопрос в том, как передавать параметры алгоритмам из библиотеки.
допустим, тебе надо протестировать некий заранее неизвестный алгоритм по нескольким параметрам. ты знаешь, сколько параметров и какие граничные значения они могут принимать. вопрос в том, как передать параметры в юзерскую функцию, без применения шаблонов и засвечивания всей внутрненней структуры.
в принципе, есть bind - уже готовое решение такой задачи, но это тоже шаблон, поэтому все классы, которые он будет использовать, должны быть видны снаружи при компиляции.
ViGOur Дата 5.11.2014, 10:35
  Ну вот сделал набросок:

"factory.h"
#ifndef FACTORY_H
#define FACTORY_H

#include <string>

class CAlgorithmBase;

template<typename TYPE>
class CFactoryBase
{
public:
    virtual TYPE *createInstance() = 0;
    virtual void destroyInstance(void *) = 0;
};

template<typename TYPE, typename BASETYPE>
class CFactoryAlgorithm : public CFactoryBase<BASETYPE>
{
public:
    TYPE *createInstance()
    {
        TYPE *pType = new TYPE();
        return pType;
    }
    void destroyInstance(void *p)
    {
        delete static_cast<TYPE*>(p);
    }
};


template<typename TYPE>
CFactoryBase<CAlgorithmBase>* MakeFactoryAlgorithm()
{
    static CFactoryAlgorithm<TYPE, CAlgorithmBase> fac;
    return &fac;
}

struct sFactoryAssocAlgorithm
{
    std::string szNameAlgorithm;
    CFactoryBase<CAlgorithmBase> *pFactory;
};


#endif // FACTORY_H
"main.cpp"
#include "factory.h"
#include <iostream>

class CAlgorithmBase
{
protected:
    std::string m_szName;
public:
    CAlgorithmBase(){m_szName = "CAlgorithmBase";}
    void print(){std::cout << "Algorithm: " << m_szName << std::endl;}
};

class CAlgo0 : public CAlgorithmBase
{
public:
    CAlgo0(){m_szName = "CAlgo0";}
};

class CAlgo1 : public CAlgorithmBase
{
public:
    CAlgo1(){m_szName = "CAlgo1";}
};

class CAlgo2 : public CAlgorithmBase
{
public:
    CAlgo2(){m_szName = "CAlgo2";}
};

sFactoryAssocAlgorithm g_algos[]=
{
    {"algo0", MakeFactoryAlgorithm<CAlgo0>()},
    {"algo1", MakeFactoryAlgorithm<CAlgo1>()},
    {"algo2", MakeFactoryAlgorithm<CAlgo2>()}
};

int main(int argc, char *argv[])
{
    int nCount = sizeof(g_algos)/sizeof(*g_algos);
    std::cout << "Algorithm count: " << nCount << std::endl;
    for( int n = 0; n < nCount; n++ )
    {
        CAlgorithmBase *pObj = g_algos[n].pFactory->createInstance();
        pObj->print();
        g_algos[n].pFactory->destroyInstance( pObj );
    }

    return 0;
}
"результат работы"
Algorithm count: 3
Algorithm: CAlgo0
Algorithm: CAlgo1
Algorithm: CAlgo2

Ну и по коду видно, что тебе остается только динамически заполнить массив g_algos, каждый элемент которого может возвращать загружаемая библиотека с тем или иным алгоритмом и все, если я конечно же тебя правильно понял...
ViGOur Дата 4.11.2014, 22:50
  Завтра мне напомните, у меня есть идейка как подобное реализовать, сейчас меня просто вырубает (спать хочется), потому лучше на завтра отложить...
Iron Bug Дата 29.10.2014, 12:04
  я не очень понимаю суть задачи. понятие плагина существует и плагины создаются по довольно стандартной схеме. на этот счёт есть много статей в сети и тут на форуме где-то были обсуждения.
если известен только первый параметр - то stdarg.h c va_list, va_arg и т.д. так работает printf, например: читает первый аргумент и вытаскивает все остальные из стека.
всё равно конечный потребитель данных знает их назначение и знает, как использовать переданные параметры.

если можешь на пальцах пояснить суть задачи - может, подскажу что-то конкретное.
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 28.3.2024, 17:55