Лучший способ загрузить QObject в DLL во время выполнения - PullRequest
0 голосов
/ 12 февраля 2020

Я столкнулся с некоторыми проблемами при 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, если вы хотите прочитать все это или проверить его .

Это мой первый пост в стеке, поэтому скажите мне, если мой пост не верный, я постараюсь отредактировать его.

...