crossplatform.ru

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

> Неопределенные классы в динамической библиотеке
Count0
  опции профиля:
сообщение 28.10.2014, 11:43
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 17
Регистрация: 30.7.2011
Пользователь №: 2772

Спасибо сказали: 0 раз(а)




Репутация:   0  


Доброго времени суток.
Возникла следующая проблема:
Для исследовательского ПО разрабатывается программный код использующий динамические библиотеки для хранения взаимозаменяемых алгоритмов.
Поскольку цель ПО - проведение исследований, то в дальнейшем планируется появление неограниченного числа новых библиотек, ни сигнатуру ни корректность функций которых не представляется возможным проконтролировать.
Поэтому пришлось разработать иерархию шаблонных классов которые принимают указатель на функцию библиотеки, описание допустимых диапазонов ее параметров, на основе которых генерирую пользовательский интерфейс для инициализации параметров, а затем по требованию пользователя запускают ее по указателю.
Таким образом, все что требуется от разработчика библиотеки создать функцию обертку которая передает все данные в синглтон-регистратор.
Вопрос в том: можно ли избежать включения всех исходников данной иерархии в динамическую библиотеку, оставив их только в основной части программы, а вбиблиотеках ограничиться опережающими объявлениями.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 9)
Iron Bug
  опции профиля:
сообщение 28.10.2014, 15:25
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


ответ: нет.
шаблоны используются только на этапе компиляции.
впрочем, если подождать лет так пять.... в последних дискуссиях по стандарту С++14 вроде как обсуждалось динамическое использование шаблонов ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Count0
  опции профиля:
сообщение 28.10.2014, 15:40
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 17
Регистрация: 30.7.2011
Пользователь №: 2772

Спасибо сказали: 0 раз(а)




Репутация:   0  


То есть придется потребовать добавлять всю иерархию в код библиотеки. А если та самая функция-регистратор обращается к singleton, чтобы передать ему данные о функцие-алгоритме, не вызовет ли повторное определение singleton в библиотеках ошибок? И корректно ли будут передаваться данные именно в singleton, инициализированный в приложении.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 28.10.2014, 15:59
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


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

вообще говоря, вопрос сигнатуры решается просто: передачей указателя. а уж на что он там указывает - это можно описывать в документации к библиотеке алгоритмов, например.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Count0
  опции профиля:
сообщение 28.10.2014, 16:04
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 17
Регистрация: 30.7.2011
Пользователь №: 2772

Спасибо сказали: 0 раз(а)




Репутация:   0  


Большое спасибо Вам.

Тут так не получится, указатель же будет void*, основной код о сигнатуре знает только возвращаемый тип и первый параметр. А динамически сгенерировать код вызова функции по описанию насколько я знаю невозможно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 29.10.2014, 12:04
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


я не очень понимаю суть задачи. понятие плагина существует и плагины создаются по довольно стандартной схеме. на этот счёт есть много статей в сети и тут на форуме где-то были обсуждения.
если известен только первый параметр - то stdarg.h c va_list, va_arg и т.д. так работает printf, например: читает первый аргумент и вытаскивает все остальные из стека.
всё равно конечный потребитель данных знает их назначение и знает, как использовать переданные параметры.

если можешь на пальцах пояснить суть задачи - может, подскажу что-то конкретное.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 4.11.2014, 22:50
Сообщение #7


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Завтра мне напомните, у меня есть идейка как подобное реализовать, сейчас меня просто вырубает (спать хочется), потому лучше на завтра отложить...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 5.11.2014, 10:35
Сообщение #8


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Ну вот сделал набросок:

"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, каждый элемент которого может возвращать загружаемая библиотека с тем или иным алгоритмом и все, если я конечно же тебя правильно понял...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 5.11.2014, 11:14
Сообщение #9


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


ViGOur, тут вопрос в том, как передавать параметры алгоритмам из библиотеки.
допустим, тебе надо протестировать некий заранее неизвестный алгоритм по нескольким параметрам. ты знаешь, сколько параметров и какие граничные значения они могут принимать. вопрос в том, как передать параметры в юзерскую функцию, без применения шаблонов и засвечивания всей внутрненней структуры.
в принципе, есть bind - уже готовое решение такой задачи, но это тоже шаблон, поэтому все классы, которые он будет использовать, должны быть видны снаружи при компиляции.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 5.11.2014, 12:18
Сообщение #10


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Тут мне кажется немного не правильный подход.
Зачем заморачиваться на функциях, когда библиотека может отдавать указатель на класс нужного в данный момент алгоритма, на основе которого будет строится GUI для данного алгоритма и отрабатывать сам алгоритм?
Причем класс может быть как стандартным (для ленивых), который работает с нужной функцией, так и расширенным пользователем (с описанием параметров и ...).

Другими словами, мы задаем некие правила, которым должны следовать пользователи, и в данном случае нам нужно будет давать пользователям только базовый класс CAlgorithmBase с правилами его использования и все...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 17:35