QEventLoop не запускается при вызове статической функции через этот указатель?

У меня есть приложение QCoreApplication, которое во время запуска загружает разные плагины QtPlugins, которые получают данные из разных источников. Эти данные возвращаются в мое приложение QCoreApplication через зарегистрированную функцию обратного вызова (одинаковую для каждого плагина). Обратный вызов регистрируется следующим образом:

// m_manager is a class variable of the class registering the callback...
pluginInterface->registerCallback(std::bind(&Manager::handleData, std::ref(m_manager), _1));

Сейчас у меня следующая проблема: В одном из плагинов данные получает сторонняя библиотека по сети. Данные будут переданы в статическую функцию-член моего класса плагина вместе с самоопределяемой структурой, которая также содержит указатель this на класс плагина. Когда я получаю данные в плагине, я теперь хочу отправить их в свое приложение QCoreApplication через зарегистрированный обратный вызов. Кроме того, я хочу создать новые объекты (например, QTimer) в функции обратного вызова. Однако кажется, что цикл событий не выполняется при вызове функции обратного вызова из статической функции-члена через указатель this класса плагина. При просмотре членов созданного объекта QTimer его указатель QAbstractEventDispatcher равен 0. Таким образом, объект QTimer не может посылать никаких сигналов, что мне крайне необходимо.

Я думал, что вызов функции обратного вызова через указатель this класса плагина (где определенно работает QEventLoop, поскольку я могу без проблем использовать сигналы/слоты внутри плагина и из других нестатических функций-членов плагина в мой QCoreApplication ). Однако похоже, что я ошибаюсь. У кого-нибудь есть объяснение описанному поведению? Если нужны какие-либо другие детали, просто спросите их, и я постараюсь их предоставить.

С уважением, Роберт


person Robert    schedule 24.07.2013    source источник
comment
Пожалуйста, покажите, как вы выполняете сетевые запросы, используя стороннюю библиотеку. В частности, является ли эта библиотека асинхронной? А почему бы вместо этого не использовать сетевой модуль Qt?   -  person Pavel Strakhov    schedule 25.07.2013
comment
Вы загружаете плагины после вызова app.exec()? Боковое примечание: для сигналов/слотов не требуется цикл обработки событий, если соединения являются прямыми (по умолчанию). Тогда это просто синхронные вызовы функций. Только соединения в очереди нуждаются в цикле событий.   -  person Frank Osterfeld    schedule 25.07.2013
comment
@FrankOsterfeld Да, плагины загружаются после вызова app.exec().   -  person Robert    schedule 25.07.2013
comment
@FrankOsterfeld При попытке создать и запустить QTimer я получаю это предупреждение: qtimer можно использовать только с потоками, запущенными с помощью qthread, и сигнал тайм-аута никогда не будет выдаваться QTimer. Как загруженный плагин, так и класс Manager работают в отдельных потоках. Потоки в основном создаются и запускаются, как показано здесь QThread. Недавно созданный таймер в диспетчере будет работать в контексте потока плагина, но, как я уже сказал, не имеет допустимого цикла.   -  person Robert    schedule 25.07.2013
comment
@Riateche Я сам не выполняю сетевые запросы напрямую. Это скрыто глубоко в сторонней библиотеке. Я только вызываю функцию, предоставленную библиотекой, которая выполняет всю тяжелую работу и вызывает статическую функцию-член моего класса (static void receiveData(void* data, void* callbackData). В callbackData я храню, например, этот указатель. Библиотека синхронна. Причина, по которой я не использую сетевую библиотеку Qt, заключается в том, что получение некоторых данных было упрощено просто ради объяснения. Библиотека выполняет массу специализированной работы, которую я не хочу делать вручную   -  person Robert    schedule 25.07.2013
comment
Если библиотека синхронна и не возвращает поток управления в цикл обработки событий, она остается занятой и не может вызывать слоты. Вам нужно создать поток и выполнять синхронные операции в этом потоке.   -  person Pavel Strakhov    schedule 25.07.2013
comment
@Riatech Ой! Это было очевидно. Спасибо за помощь, это была проблема.   -  person Robert    schedule 25.07.2013


Ответы (1)


Если библиотека синхронна и не возвращает поток управления в цикл обработки событий, она остается занятой и не может вызывать слоты. Вам нужно создать поток и выполнять синхронные операции в этом потоке.

person Pavel Strakhov    schedule 25.07.2013