Название: Qt из dll без GUI Отправлено: kuzulis от Апрель 07, 2014, 17:47 Доброго всем времени.
Есть необходимость запихнуть Qt-шный QCoreApplication в DLL. Знаю что тема уже сто-пицот раз обсуждалась, но моя проблема немного специфичная. Имеем некую DLL которая экспортирует чисто COM-интерфейсы без всякого GUI и прочего. Эту dll-ку подгружает некий виндовый сервис самостоятельно, без моего участия. В принципе, если реализовать все необходимые "фичи" внутри dll-ки, используя Win API - то проблем нет. Но дело в том, что внутри dll-ка общается при помощи пайпов с некой программной-сервером с использованием некоего самопального RPC протокола. Проблема в том, что этот сервер и RPC протокол реализован на Qt, и кроме dll-ки к серверу коннектятся и иные Qt-шные программы-клиенты. Поэтому RPC протокол сделан на Qt и он как-бы общий; делать этот RPC протокол еще и отдельно на Win API для dll-ки у меня не хватает духу - да и накладно. :) Хотелось бы впихнуть уже готовое это дело внутрь DLL. Знаю как-бы два способа это сделать: 1. Через создание экземпляра QCoreApplication в отдельном треде QThread внутри dll-ки. 2. Использовать QtWinMigrate solution (https://qt.gitorious.org/qt-solutions/qt-solutions/source/fd22bee22274975c56f1c10d87ee9fd2c0818f83:qtwinmigrate) Сделал пока что по п.1. Вроде с наскоку оно работает, но сыпет всякими ворнингами: Цитировать ... [4152] [default] bool __cdecl check_parent_thread(class QObject *,class QThreadData *,class QThreadData *): QObject: Cannot create children for a parent that is in a different thread. ... мне не нравится это, ну вообще, не нравится.. Хочу как-то передалеть на п.2. , немного перекодив солюшен под себя (выдернуть только необходимое из него). Но проблема в том, что этот солюшен заточен для GUI приложений. И Qt-шный цикл событий "замещается" циклом событий от WinAPI - шного окна (т.е. как-бы берется от WinAPI - шного окна, как я понял). Но в моей dll-ке нету никаких внешних методов которые создавали бы WinAPI-шные окошки, есть только медод: DllGetClassObject (http://msdn.microsoft.com/en-us/library/windows/desktop/ms680760%28v=vs.85%29.aspx) Код
в котором создаются некие COM-объекты.. :) ЗЫ: Естественно, есть и DllMain() в которой можно обработать DLL_PROCESS_DETACH/ATTACH но я умалчиваю об этом. Т.е., главная проблема - как запустить цикл сообщений для QCoreApplication ? т.к. нету никаких окошечек чтобы взять оттуда.. Пока думаю о возможности запускать WinAPI-шный таймер и в его callback-функции дергать: Код
например, с периодичностью в 10 мсек... Но, кажется, что это будет сказываться на работе RPC с использованием QLocalSocket.. Есть у кого какие-нить идеи? Может кто победил это? :) Название: Re: Qt из dll без GUI Отправлено: Bepec от Апрель 07, 2014, 18:50 Эммм. По моей статейке делали тред внутри?
Насколько я помню network работает нормально в таких dll без варнингов. Название: Re: Qt из dll без GUI Отправлено: vregess от Апрель 07, 2014, 20:25 Тоже выдирал из QtWinMigrate.
Может такое подойдет: Код Единственное поменять QApplication на QCoreApplication. Это для qt4. Код
А создавать QApplication и GUI в потоке плохая идея. По крайней мере у меня ничего не получилось. Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 07, 2014, 20:29 Цитата: Bepec Эммм. По моей статейке делали тред внутри? Продублирую тут похожие посты: Создание dll с сигнал-слотами внутри для NoQt приложений. (http://www.prog.org.ru/topic_25323_0.html) Dll на Qt + QTcpSocket для вызова не в Qt-приложении (http://www.prog.org.ru/topic_25307_0.html) Да, сделал примерно то-же самое что и ты, только использовал QThread вместо ::CreateTread(), вроде оно работает и так (хотя, ты упоминал что не должно :) ) Но мне так не нравится, т.к. нужно заморачиваться с критическими секциями и прочей синхронизацией.. Глянул еще на твой код отсюда (http://qtsimple.blogspot.ru/2013/10/dll-noqt.html): Код
и вижу, что ты делаешь: Код
зачем? Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 07, 2014, 20:41 Цитата: ck Тоже выдирал из QtWinMigrate. Да, я аналогичное пробовал, но не понял, как использовать.. :) Например, (грубо) реализовал я init()/deinit() с хуком и имею единственную паблик ф-ю DllGetClassObject (подставь любое имя :) ) из dll-ки: Код
в которой нужно создавать не виджеты, а обычные QObject-ы.. Так вот, вопрос: как это сделать чтобы цикл заработал? Нужно что-то вроде этого: Код
Т.е., мне не нужно экспортировать создаваемые Qt-шные объекты во вне dll-ки, нужно просто заставить крутиться луп внутри.. Название: Re: Qt из dll без GUI Отправлено: Bepec от Апрель 07, 2014, 21:26 1) Я делаю new для того, чтобы созданную мной переменную впоследствии можно было бы удалить.
Но не пойму проблемы. Цикл в моём примере работает 100%. Он до сих пор на одной машине крутится. Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 07, 2014, 21:46 Цитировать 1) Я делаю new для того, чтобы созданную мной переменную впоследствии можно было бы удалить. Не понял, о какой переменной речь? Меня смущает создание QLibrary из library... Это просто для примера и можно заменить на QObject, или в вызове new QLibrary есть сакральный смысл? :) Цитировать Но не пойму проблемы. Цикл в моём примере работает 100%. Он до сих пор на одной машине крутится. Да, работать оно будет, но много проблем с синхронизацией и пр.. хотелось бы без лишних тредов использовать.. Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 07, 2014, 21:56 UPD: Попробовал для Qt5 собрать этот пример из солюшенов:
https://qt.gitorious.org/qt-solutions/qt-solutions/source/fd22bee22274975c56f1c10d87ee9fd2c0818f83:qtwinmigrate/examples/qtdll но при вызове ф-ции Код
из dll-ки, оно крешится (все зависимости по Qt-шным и прочим рантайм dll-кам удовлетворил).. Правда, я вызываю ее с нулевым HWND parent - может в этом проблема... :) Цитировать e:\git\qtwinmigrate\examples\build-qtdllapp-Desktop_Qt_5_2_1_MinGW_4_8_32bit-Debug\debug>qtdllapp.exe QWidget: Must construct a QApplication before a QWidget This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. также смущает: "Must construct a QApplication before a QWidget".. Как так? Ведь QApplication уже должно быть создано первым после вызова LoadLibrary().. Название: Re: Qt из dll без GUI Отправлено: Bepec от Апрель 07, 2014, 22:05 Да, чуть невнятно.
dllClass это любой класс, который будет находиться в dll :) Сакральный смысл в областях видимости. При выходе из функции локальный объект удалится. Создание объекта с New даёт ему возможность жить бессрочно в потоке с активным евент лупом. Насчёт синхронизации, тут у меня пробелы с теорией. Сия проблема мне не ясна. Разбалован я сигнально-слотовой системой. Все доступные на момент написания моей темы статьи и примеры отказывались работать, или работали через раз. Мигрейт помоему не запускал цикл и ругался подобным способом. PS Проще выражаясь, QWidget был создан в потоке, в котором не запущен/не существует QApplication :) Это и было моей основной проблемой, сподвигнувший на изыскания :) PPS создан то он создан, но вот виджет к нему доступ не может получить. PPPS если тестовый примерчик сделаете с нужным вам функционалом, я его и свои изыскания попытаюсь совместить. Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 07, 2014, 22:19 Накопал кое-что тут: http://stackoverflow.com/questions/2150488/using-a-qt-based-dll-in-a-non-qt-application
суть - не использовать всякие треды, а просто вызывать qApp->processEvents() в каллбеке от WinAPI-шного таймера (как я и хотел ранее сделать).. завтра попробую это.. :) Название: Re: Qt из dll без GUI Отправлено: Bepec от Апрель 07, 2014, 23:08 В путь, если получится будет прикольно :)
Название: Re: Qt из dll без GUI Отправлено: vregess от Апрель 08, 2014, 07:18 Да, я аналогичное пробовал, но не понял, как использовать.. :) Не совсем понял, оно уже должно работать... Код
суть - не использовать всякие треды, а просто вызывать qApp->processEvents() в каллбеке от WinAPI-шного таймера (как я и хотел ранее сделать).. Так я это и делаю, разве не так? Ну почти. У меня хук не на события таймера, а на все события очереди.Хочу сказать, DLLWrapper работает в одном проекте, полет нормальный. Есть виндовая прога, к ней подключаются плагины. Вот один из плагинов написан на qt4. DLLWrapper ставит хук на очередь сообщений главного потока хост-программы, и там обрабатываются евенты Qt. Проверить это просто. Выполнить долгую операцию в каком-нить обработчике, например в слоте. В это время хост-программа перестанет обрабатывать свои события. Поэтому В путь, если получится будет прикольно :) уже прикольно, тк получилось.А все эти заигрывания с потоками до добра не доведут) Название: Re: Qt из dll без GUI Отправлено: Bepec от Апрель 08, 2014, 11:04 Собственно нужна очередь сообщений окна. А для консольных приложений как делать?
Название: Re: Qt из dll без GUI Отправлено: Igors от Апрель 08, 2014, 11:19 Прошлой осенью "инжектировал" Qt окна в не-Qt приложение. QApplication создал прямо в главной нитке, сначала поставил нативные обработчики и, если событие не обработано, то автоматом вызываются обработчики Qt. Да, работает, но это коряво, все время приходится латать
Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 08, 2014, 13:19 В общем, вроде заработало в методе с таймером (у меня на примере моего проекта с dll-кой COM интерфейсов):
dll.h Код
dll.cpp Код
Ранее я пробовал вариант с хуками, и, кажется, они не работали.. Хотя, может я накосячил где-то там... :) Название: Re: Qt из dll без GUI Отправлено: xokc от Апрель 08, 2014, 20:11 А не смущает при такой реализации "скважность" в 1 мс при обработке Qt событий, особенно с учетом того, что это часть неких "сервиса" и "сервера" с
Название: Re: Qt из dll без GUI Отправлено: vregess от Апрель 09, 2014, 07:54 Собственно нужна очередь сообщений окна. А для консольных приложений как делать? Вроде как очередь сообщений окна не нужна, будет работать и с консольным хост-приложением. Хук цепляется к сообщениям потока (см. SetWindowsHookEx). PS сам я на консольном приложении не тестировал. Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 09, 2014, 10:21 Цитата: xokc А не смущает при такой реализации "скважность" в 1 мс при обработке Qt событий, особенно с учетом того, что это часть неких "сервиса" и "сервера" с блек-джеком и шл.. пайпом и COM интерфейсами? Всё-таки на современных процессорах за это время уйму полезных вещей сделать можно. Или там у Вас система уж совсем не "реал-тайм"? Скорее всего в моем случае это некритично, т.к. задача спецфическая.. :) Цитата: ck PS сам я на консольном приложении не тестировал. Щас попробую на хуки переписать и посмотеть что получится. Название: Re: Qt из dll без GUI Отправлено: kuzulis от Апрель 09, 2014, 10:47 Цитировать Щас попробую на хуки переписать и посмотеть что получится. Не, хуки не работают.. Нет времени разбираться.. |