Название: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Июля 20, 2013, 11:21 Добрый день.
Помогите, пожалуйста, понять в чем может быть проблема. Имеется приложение написанное на Delphi и библиотека для связи с удаленным серваком по TCP написанная на Qt с использованием QTcpSocket. Для того, чтобы в библиотеке работал Qt-eventloop в DllMain библиотеки завожу поток и запускаю в его контексте QCoreApplication::exec(). После этого при вызове библиотечной функции происходит инициализация работы библиотеки, а именно - запускается поток, в контексте которого заводится QTcpSocket. Связываются сигналы со слотами и т.д. Данные приходят и обрабатываются. Реализовано завершение работы библиотеки с удалением сокета и остановкой потока... Все работает! Но есть одна проблема - основная прога виснет при попытке выгрузить библиотеку. а именно на вызове FreeLibrary. Выяснилось, что если в библиотеке не вызывать connectToHost() то она выгружается благополучно. Отзовитесь, кто сталкивался с подобным? Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: merke от Июля 20, 2013, 13:04 Происходит ли при выгрузке либы вызов внутри нее функции дисконекта от хоста, остановка потоков и так далее?
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Июля 20, 2013, 15:04 Дисконнект, остановка потока, удаление сокета и потока происходит еще до выгрузки библиотеки, посредством вызова ее функции. И только после этого пытаюсь выгрузить библиотеку.
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Июля 20, 2013, 15:13 Что значит "запускаю в его контексте QCoreApplication::exec()"?
Завершается цикл нормально? Почему не использовать QEventLoop? Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Июля 20, 2013, 15:35 Что значит "запускаю в его контексте QCoreApplication::exec()"? Завершается цикл нормально? Почему не использовать QEventLoop? Создаю поток, связываю сигнал started() c Qt::DirectConnection со слотом, в котором запускается QCoreApplication::exec(). Т.е. QCoreApplication запускаестя из потока, для того, чтобы не блокировалась загрузка библиотеки в DllMain. При этом Qt выводит сообщение, о том, что QCoreApplication запущен не в основном потоке, но связка сигналов все равно работает. С завершением потока, в котором запущен QCoreApplication::exec() проблем нет т.к. либа не выгружается, только если делали connectToHost(). В любом случае связка от таймеров отрабатывается, и все вертится как надо. К тому же в последствии я выделил запуск потока с QCoreApplication в отдельную библиотеку, которую вообще не выгружаю. А разве можно использовать QEventLoop без QCoreApplication??? Я пробовал, но Qt ругается и коннекты не обрабатывает. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Июля 20, 2013, 15:42 При этом Qt выводит сообщение, о том, что QCoreApplication запущен не в основном потоке, но связка сигналов все равно работает. Вот это меня и смущает.Экземпляр QCoreApplication создавать придется все равно, а после этого можно использовать QEventLoop в нужных местах. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Июля 20, 2013, 16:18 При этом Qt выводит сообщение, о том, что QCoreApplication запущен не в основном потоке, но связка сигналов все равно работает. Вот это меня и смущает.Экземпляр QCoreApplication создавать придется все равно, а после этого можно использовать QEventLoop в нужных местах. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Июля 20, 2013, 16:29 что либа не выгружается, только если я сделаю connectToHost(). Метод connectToHost выполняется асинхронно, т.е. eventloop для него жизненно важен. Вы создаете экземпляр QCoreApplication в одном потоке, а цикл запускаете в другом. Qt об этом вас предупреждает.Я вам предлагаю попробовать использовать локальный объект QEventLoop внутри нитки, который при ее завершении разрушиться. А QCoreApplication::exec оставить в покое. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Августа 17, 2013, 10:56 Дело в том, что QEventLoop не фунциклирует без QApplication. При его запуске, Qt так об этом и говорит. Может я чего-то не так делаю? Есть пример кода?
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Августа 17, 2013, 12:09 Дело в том, что QEventLoop не фунциклирует без QApplication. При его запуске, Qt так об этом и говорит. Может я чего-то не так делаю? Есть пример кода? Конечно не функционирует, объект QCoreApplication/QApplication придется создавать все равно. Но в дочерних потоках не нужно использовать его метод exec, лучше создавать свои экземпляры QEventLoop.Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Августа 17, 2013, 12:25 Итак:
1) Приложение не на Qt и QCoreApplication в нем НЕТ! 2) DLL использует QThread , обрабатывает данные от сокета АСИНХРОННО в потоке. Где должен создаваться QCoreApplication??? И где вызывать его метод exec()? Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Августа 17, 2013, 13:00 Итак: Например в DllMain.1) Приложение не на Qt и QCoreApplication в нем НЕТ! 2) DLL использует QThread , обрабатывает данные от сокета АСИНХРОННО в потоке. Где должен создаваться QCoreApplication??? И где вызывать его метод exec()? Его метод exec нигде вызывать не надо. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Августа 17, 2013, 13:22 А если НИГДЕ НЕ ВЫЗЫВАТЬ exec(), то как будут сообщения то доходить???
Вы так пробовали??? Работает? Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Августа 17, 2013, 13:28 А если НИГДЕ НЕ ВЫЗЫВАТЬ exec(), то как будут сообщения то доходить??? ::)В рабочих потоках, в методе run, нужно использовать свои объекты QEventLoop и их метод exec или использовать метод exec QThread (что по сути одно и тоже). Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Bepec от Августа 17, 2013, 13:34 Тут закавыка интересная. QThread не запуститься без QApplication. Точнее не запуститься его цикл событий.
Я добился работы только при создании отдельного winApi потока. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Августа 17, 2013, 13:40 Тут закавыка интересная. QThread не запуститься без QApplication. Точнее не запуститься его цикл событий. А в чем проблема создавать экземпляр QCoreApplication?Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Августа 17, 2013, 13:40 В Dllmain при DLL_PROCESS_ATTACH: создаю объект QCoreApplication core(argc,0);
НЕ ВЫЗЫВАЮ exec(); создаю поток QThread() и в методе run(); вызываю exec(); то Qt выдаeт: "QEventLoop: Cannot be used without QApplication" и соответственно сигналы не работают. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Августа 17, 2013, 13:43 А зачем его создавать, если eventloop не запускать?
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Bepec от Августа 17, 2013, 13:48 eventLoop не запускается, если он не создан в отдельном WinApi потоке.Во всяком случае мне его заставить работать не удалось без потока. Мб чуть попозже посмотрю свои исходники - кину.
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: dim.lian_net от Августа 17, 2013, 14:09 А без QCoreApplication::exec() он может работать?
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Old от Августа 17, 2013, 14:11 В Dllmain при DLL_PROCESS_ATTACH: создаю объект QCoreApplication core(argc,0); Ага. Создаете экземпляр QApplication на стеке и он разрушается при выходе из DllMain.НЕ ВЫЗЫВАЮ exec(); создаю поток QThread() и в методе run(); вызываю exec(); то Qt выдаeт: "QEventLoop: Cannot be used without QApplication" и соответственно сигналы не работают. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: xokc от Октября 03, 2013, 15:47 И всё-таки, кому-нибудь удалось запустить механизм сигнал/слот внутри dll из консольного не Qt Windows приложения?
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Bepec от Октября 03, 2013, 16:39 Из консольного не пробовал, но из обычного получалось.
Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: xokc от Октября 04, 2013, 09:29 Из консольного не пробовал, но из обычного получалось. Неоднократно тут на форуме встречал твоё обещание выложить кусочек кода на эту тему :).Если не затруднит, покажи свою реализацию DLLMain. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: Bepec от Октября 04, 2013, 09:33 Омм... Это да, постоянно забываю найти и выложить.
PS если ещё припомнишь что я там обещал выложить - напиши в ЛС. А то пипец на работе заставляет забывать :) Разгрести надо. Название: Re: Dll на Qt + QTcpSocket для вызова не в Qt-приложении Отправлено: xokc от Октября 09, 2013, 15:11 Раз уж публично попрекнул Вереса невыполнением обещаний, публично и поблагодарю.
Тут обещанное выложено http://www.prog.org.ru/topic_25323_0.html И таки-да, оно работает. Проблема у меня лично была в том, что для того, чтобы заработали циклы обработки сообщений в DLL нужно было все объекты, которые участвуют в процессе сигнал/слот, создавать в той же потоковой функции, где создается QCoreApplcation. |