Я столкнулся с некоторыми проблемами при dynamici c загрузке Dll, содержащей QObject без потери механизма сигнал / слот .
Я закончил тем, что что-то работало хорошо, но подумал, что, может быть, я полностью переборщил и пропустил что-то, что могло бы сильно помочь ... Я собираюсь go пройти через основные шаги, которые я предпринял в своем окончательном коде.
Хорошо, давайте начнем с контекста.
Я хорошо знаком с использованием Dll, содержащего QObject, полученного "stati c way" со свойствами, которые я могу напрямую использовать в коде qml:
class MyLIB_EXPORT MyLib : public QObject {
Q_OBJECT
Q_PROPERTY( int property READ getProp WRITE setProp NOTIFY propChanged )
public :
int getProp ( void );
void setProp ( int p );
signals :
void propChanged ( void );
}
связанный с проектом с этими строками в .pro:
INCLUDEPATH += $$PWD/../MyLib/
win32: LIBS += -L$$OUT_PWD/../MyLib/ -lMyLib
До сих пор я был вполне доволен этим ...
Проблема в том, Эти dll становятся обязательными для запуска программы, и теперь мне нужно иметь возможность не включать dll и запустить программу, просто отключив эту часть.
Причина, по которой я хочу не включать эту dll файл:
- Использование пространства для пользователя (нет необходимости отправлять бесполезные dll)
- Время запуска (каждая загрузка dll при запуске занимает все больше и больше времени)
Я начал смотреть на этот великолепный механизм получения указателя на функцию из dll с помощью QLibrary.
typedef void ( *t_init )( void );
t_init f_init = (t_init) QLibrary->resolve( "init" );
Это довольно тяжело, потому что я должен делать это с каждой функцией, но я в порядке, чтобы заплатить цену .
В конце концов я нашел какой-то способ использовать «обработчик»
// Create handle to keep a pointer to an instance of the class MyDynamicLibHandler
typedef MyDynamicLib* MyDynamicLibHandler;
// Function that creates an instance of MyDynamicLibHandler.
MYDYNAMICLIB_EXPORT
MyDynamicLibHandler getHandle ( void );
// Function that allow to use the object referenced by the handle
MYDYNAMICLIB_EXPORT
int getMyValue ( MyDynamicLibHandler handle ); // return handle->getMyValue
В какой-то момент у меня был рабочий пример динамической библиотеки c, которая была загружена во время выполнения библиотекой stati c.
НО
Я не смог заставить работать механизм сигналов QT ...
Единственное решение, которое я нашел до сих пор, - это использовать другой объект, MySignalEmiter, который будет использоваться совместно эти два класса будут способны излучать сигнал, когда MyDynamicLib нуждается в этом, а StaticDynamicLoader может подключить его к чему-то другому.
class MYSIGNALEMITER_EXPORT MySignalEmiter : public QObject
{
Q_OBJECT
public:
void emitMyValueChanged ( void ){ myValueChanged() ; }
signals:
void myValueChanged ( void );
};
StaticDynamicLoader подключает сигнал к сигналу Q_PROPERTY:
m_signalEmiter = f_getSignalEmiter( m_handle );
QObject::connect( m_signalEmiter ,
&MySignalEmiter::myValueChanged ,
this ,
&StaticDynamicLoader::valueChanged );
MyDynamicLib создать экземпляр MySignalEmiter и использовать его для «генерации» сигналов
MyDynamicLib::MyDynamicLib()
{
m_mySignalEmiter = new MySignalEmiter;
}
MySignalEmiter* MyDynamicLib::getSignalEmiter()
{
return m_mySignalEmiter;
}
void MyDynamicLib::setMyValue( int val )
{
m_myVal = val;
m_mySignalEmiter->emitMyValueChanged();
}
В конце концов, у меня что-то работает, и я в порядке с этими "уловками", но я не могу не думать, что должны быть другие способы.
Я пропускаю что-то ? Есть ли лучшие способы динамически связать QObject? Есть ли проблемы с тем, как я это сделал
Весь код находится на github, если вы хотите прочитать все это или проверить его .
Это мой первый пост в стеке, поэтому скажите мне, если мой пост не верный, я постараюсь отредактировать его.