Russian Qt Forum
Май 19, 2024, 12:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Dll на Qt + QTcpSocket для вызова не в Qt-приложении  (Прочитано 14913 раз)
dim.lian_net
Гость
« : Июль 20, 2013, 11:21 »

Добрый день.
Помогите, пожалуйста, понять в чем может быть проблема.
Имеется приложение написанное на Delphi и библиотека для связи с удаленным серваком по TCP написанная на  Qt с использованием QTcpSocket. Для того, чтобы в библиотеке работал Qt-eventloop в DllMain библиотеки завожу поток и запускаю в его контексте QCoreApplication::exec().
После этого при вызове библиотечной функции происходит инициализация работы библиотеки, а именно - запускается поток, в контексте которого заводится QTcpSocket. Связываются сигналы со слотами и т.д. Данные приходят и обрабатываются. Реализовано завершение работы библиотеки с удалением сокета и остановкой потока...
Все работает! Но есть одна проблема - основная прога виснет при попытке выгрузить библиотеку. а именно на вызове FreeLibrary. Выяснилось, что если в библиотеке не вызывать connectToHost() то она выгружается благополучно.
Отзовитесь, кто сталкивался с подобным?
Записан
merke
Гость
« Ответ #1 : Июль 20, 2013, 13:04 »

Происходит ли при выгрузке либы вызов внутри нее функции дисконекта от хоста, остановка потоков и так далее?
Записан
dim.lian_net
Гость
« Ответ #2 : Июль 20, 2013, 15:04 »

Дисконнект, остановка потока, удаление сокета и потока происходит еще до выгрузки библиотеки, посредством вызова ее функции. И только после этого пытаюсь выгрузить библиотеку.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Июль 20, 2013, 15:13 »

Что значит "запускаю в его контексте QCoreApplication::exec()"?
Завершается цикл нормально?
Почему не использовать QEventLoop?
Записан
dim.lian_net
Гость
« Ответ #4 : Июль 20, 2013, 15:35 »

Что значит "запускаю в его контексте QCoreApplication::exec()"?
Завершается цикл нормально?
Почему не использовать QEventLoop?


Создаю поток, связываю сигнал started() c Qt::DirectConnection со слотом, в котором запускается QCoreApplication::exec(). Т.е. QCoreApplication запускаестя из потока, для того, чтобы не блокировалась загрузка библиотеки в DllMain. При этом Qt выводит сообщение, о том, что QCoreApplication запущен не в основном потоке, но связка сигналов все равно работает.

С завершением потока, в котором запущен QCoreApplication::exec() проблем нет т.к. либа не выгружается, только если делали connectToHost(). В любом случае связка от таймеров отрабатывается, и все вертится как надо.
К тому же в последствии я выделил запуск потока с QCoreApplication  в отдельную библиотеку, которую вообще не выгружаю.

А разве можно использовать QEventLoop без QCoreApplication??? Я пробовал, но Qt ругается и коннекты не обрабатывает.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #5 : Июль 20, 2013, 15:42 »

При этом Qt выводит сообщение, о том, что QCoreApplication запущен не в основном потоке, но связка сигналов все равно работает.
Вот это меня и смущает.

Экземпляр QCoreApplication создавать придется все равно, а после этого можно использовать QEventLoop в нужных местах.
Записан
dim.lian_net
Гость
« Ответ #6 : Июль 20, 2013, 16:18 »

При этом Qt выводит сообщение, о том, что QCoreApplication запущен не в основном потоке, но связка сигналов все равно работает.
Вот это меня и смущает.

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

Дык я и создаю, но создаю его не в основном потоке. Он и крутится в этом потоке, при этом пробрасывает мне сигналы. Но дело то не в этом, а в том, что либа не выгружается, только если я сделаю connectToHost(). Такое впечатление, что ранне сконнекченый сокет удаляется не так, как сокет, который не коннектился (несмотря на disconnectFromHost(), close(), abort() и т.д.). Причем под отладчиком если встать на выгрузке либы и пробежаться по деструкторам, оно иногда выгружается. Как будто требуется время, чтобы освободить какие-то ресурсы.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #7 : Июль 20, 2013, 16:29 »

что либа не выгружается, только если я сделаю connectToHost().
Метод connectToHost выполняется асинхронно, т.е. eventloop для него жизненно важен. Вы создаете экземпляр QCoreApplication в одном потоке, а цикл запускаете в другом. Qt об этом вас предупреждает.
Я вам предлагаю попробовать использовать локальный объект QEventLoop внутри нитки, который при ее завершении разрушиться.
А QCoreApplication::exec оставить в покое.

Записан
dim.lian_net
Гость
« Ответ #8 : Август 17, 2013, 10:56 »

Дело в том, что QEventLoop не фунциклирует без QApplication. При его запуске, Qt так об этом и говорит. Может я чего-то не так делаю? Есть пример кода?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #9 : Август 17, 2013, 12:09 »

Дело в том, что QEventLoop не фунциклирует без QApplication. При его запуске, Qt так об этом и говорит. Может я чего-то не так делаю? Есть пример кода?
Конечно не функционирует, объект QCoreApplication/QApplication придется создавать все равно. Но в дочерних потоках не нужно использовать его метод exec, лучше создавать свои экземпляры QEventLoop.
Записан
dim.lian_net
Гость
« Ответ #10 : Август 17, 2013, 12:25 »

Итак:
1) Приложение не на Qt и QCoreApplication в нем НЕТ!
2) DLL использует QThread , обрабатывает данные от сокета АСИНХРОННО в потоке.
Где должен создаваться QCoreApplication???
И где вызывать его метод exec()?
« Последнее редактирование: Август 17, 2013, 12:27 от dim.lian_net » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #11 : Август 17, 2013, 13:00 »

Итак:
1) Приложение не на Qt и QCoreApplication в нем НЕТ!
2) DLL использует QThread , обрабатывает данные от сокета АСИНХРОННО в потоке.
Где должен создаваться QCoreApplication???
И где вызывать его метод exec()?
Например в DllMain.
Его метод exec нигде вызывать не надо.
Записан
dim.lian_net
Гость
« Ответ #12 : Август 17, 2013, 13:22 »

А если НИГДЕ НЕ ВЫЗЫВАТЬ exec(), то как будут сообщения то доходить???
Вы так пробовали??? Работает?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #13 : Август 17, 2013, 13:28 »

А если НИГДЕ НЕ ВЫЗЫВАТЬ exec(), то как будут сообщения то доходить???
Строит глазки
В рабочих потоках, в методе run, нужно использовать свои объекты QEventLoop и их метод exec или использовать метод exec QThread (что по сути одно и тоже).
Записан
Bepec
Гость
« Ответ #14 : Август 17, 2013, 13:34 »

 Тут закавыка интересная. QThread не запуститься без QApplication. Точнее не запуститься его цикл событий.

Я добился работы только при создании отдельного winApi потока.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 19.