Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Bepec от Июль 23, 2013, 10:27



Название: Создание dll с сигнал-слотами внутри для NoQt приложений. [РЕШЕНО]
Отправлено: Bepec от Июль 23, 2013, 10:27
Тема решена. Руководство по написанию dll - http://qtsimple.blogspot.ru/2013/10/dll-noqt.html. Исходники там же.

Приветствую. Тут в связи с темой внедрения dll появилась необходимость в отладочной длл, которая позволяет рассылать и обрабатывать сообщения, дергая сишные функции.

Проблема: В библиотеке не работают сигнал-слоты

Что делал: почитал темы, понял основную мысль - нужно запускать свой event-loop/QCoreApplication в dll.

И тут встаёт вопрос - запуск event-loop'а в самой dll (в Dllmain при аттаче dll) убивает её (exec длится до бесконечности).

Запуск event-loop'a в отдельном потоке - сигнал-слоты не работают.

Как правильно сделать?

PS поиск терзал - пара результатов идут без окончательного решения.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений.
Отправлено: Bepec от Июль 23, 2013, 12:15
Пока что набрёл на кривой костыль.

Запустить луп, послать сигнал. В слоте убить первый луп и включить второй, основной. В результате программа пойдёт дальше исполняться и в dll появится цикл сообщений.

PS но криво как то :D Мб кто подскажет получше вариант?


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений.
Отправлено: ViTech от Июль 23, 2013, 12:50
Смотря какая связь между сигнал-слотами нужна. С Qt::DirectConnection и без лупа должно работать, только тогда слот будет выполняться в потоке сигнала. А так да, придется извращаться :).


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений.
Отправлено: Bepec от Июль 23, 2013, 12:52
Direct - это стандартный прямой вызов. А нужна работа асинхронных интерфейсов аля QTcpSocket.

update: консольная утилита с таким извращение работать не хочет :(


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений.
Отправлено: Bepec от Июль 23, 2013, 14:34
Сам себе отвечу.

Из-за ограничений QCoreApplication / QApplication должны быть вызваны в главном потоке (раз).
Exec может быть вызван только из того потока,в котором они были созданы (главный поток) (два).
Так же для корректной работы их обоих необходимо "окно" программы, получающее системные сообщения (верно для Windows). (три)

Вышеприведённые факты не позволяет использовать их в inject - dll. Да и в обычных не очень. (Верно для приложений, не имеющих собственного QApplication/QCoreApplication).

Исправить ситуацию вероятно можно, но необходимы серьёзные хаки. Засим тему считаю "Решенной".

PS было упоминание о некоей библиотеке, реализующей полнофункциональный цикл событий в dll, но к сожалению ссылки битые. Дополнительной информации нет :(


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений.
Отправлено: ViTech от Июль 23, 2013, 15:06
PS было упоминание о некоей библиотеке, реализующей полнофункциональный цикл событий в dll, но к сожалению ссылки битые. Дополнительной информации нет :(

Может это QMfcApp (http://doc.qt.digia.com/solutions/4/qtwinmigrate/qmfcapp.html), костыль старый и заброшенный, но если сильно захотеть, то, наверное, можно прикрутить :).


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 23, 2013, 15:37
Вроде именно про него говорили. Скачал, смотрю.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Akon от Июль 23, 2013, 17:38
В длл не использовать поток приложения, а создать свой и в нем крутить эвентлооп для асинхронных сокетов.

Если же все-таки задаться целью не создавать дополнительные потоки, то нужно смотреть как QEventLoop сцепляется с API ::GetMessage() - возможно, будет зацепка.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 23, 2013, 19:44
У меня задачка чуть интереснее. Я инжектю dll в чужой процесс в отдельный поток ) Засим создать свой луп нельзя из-за вышеприведённых ограничений )


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 23, 2013, 19:47
У меня задачка чуть интереснее. Я инжектю dll в чужой процесс в отдельный поток ) Засим создать свой луп нельзя из-за вышеприведённых ограничений )
Тогда в цикл того процесса нужно добавить обработку Qt очереди сообщений иначе никак.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 23, 2013, 20:42
В том и закавыка что это практически нереально :D
Я и бьюсь то над тем, чтобы перехватывать сообщения винды у процесса. Пока не очень получается - существуют ограничения )


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 23, 2013, 21:05
В том и закавыка что это практически нереально :D
Я и бьюсь то над тем, чтобы перехватывать сообщения винды у процесса. Пока не очень получается - существуют ограничения )
Кто-то должен регулярно обрабатывать очередь Qt-сообщений. Если исследуемый процесс этого делать не может, нужно найти того, кто сможет.
Ну не знаю... можно запускать какой-то вендовый таймер, при срабатывании которого будет вызываться processEvents.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 23, 2013, 23:30
В том и закавыка. Я пока не очень понимаю принцип работы цикла событий Qt. Евент лупы гундят, exec'кутятся, но сигналы не доходят. application'ы не заводятся, возвращают вышеприведённые ошибки. Вроде грят с помощью вами упомянутой библиотеки могут создавать, но я пока не смог добиться никакого результата :P

PS информации море, полезной нет.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 24, 2013, 08:10
Расскажите подробней о задаче.
Можно использовать свой QEventLoop в каждой функции, можно запустить отдельный поток и в нем крутить этот цикл.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Igors от Июль 24, 2013, 08:47
В длл не использовать поток приложения, а создать свой и в нем крутить эвентлооп для асинхронных сокетов.
Не вижу почему это не должно работать. Ну плюс одна нитка - невеликая проблема. Посылать ей сигналы события (из главной) можно. Принимать - хоть по таймеру, а лучше синхронизировать через мутекс или семафор


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 08:49
Подробнее:

Имеется подопытный процесс с неизвестным содержимым (ахз на чем написано).

Мы желаем внедрить в него свой код.

Самый простой способ - создать в процессе remoteThread и заставить его загрузить нашу dll.

dll грузится в контексте и адресном пространстве подопытного процесса. Всё гуд.

Хочется её отладить, вывести ошибки, смотреть сообщения.

Сейчас реализована посылка сообщений определённому окну с текстовой информацией, но особо много туда не пошлёшь и работает через раз, что не устраивает.

Хочется варианта аля запихать свой отладочный Qt класс в dll. И вот тут начинаются чудеса.

Класс создаётся, конструктор и иже с ним отрабатывают.  Работоспособность равна прямым коннектам.

Запуск eventLoop не запускает обработку событий. Т.е. он запускается, виснет в exec и всё. Подвешивает dll. Сигналы как не доходили так и не доходят.


to Igors: Проблема что нет или есть, но нет доступа к главному потоку приложения. :P


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 24, 2013, 09:27
Запуск eventLoop не запускает обработку событий. Т.е. он запускается, виснет в exec и всё. Подвешивает dll. Сигналы как не доходили так и не доходят.
Где и как вы запускаете цикл событий?


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 09:37
Ыть хочу спойлеры.

Вкратце - создаётся класс при подгрузке Dll.
Код:
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
)
{
        HWND currentHwnd_ = FindWindow(NULL, L"Debugger");

switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
appThread* t = new appThread;
                        QEventLoop loop;
                        loop.exec();
}
break;
case DLL_THREAD_ATTACH:
SendMessage(currentHwnd_, WM_SETTEXT, 0, (long)_T("DLL_THREAD_ATTACH..."));
break;
case DLL_THREAD_DETACH:
SendMessage(currentHwnd_, WM_SETTEXT, 0, (long)_T("DLL_THREAD_DETACH..."));
break;
case DLL_PROCESS_DETACH:
SendMessage(currentHwnd_, WM_SETTEXT, 0, (long)_T("DLL_PROCESS_DETACH..."));
break;
}
return TRUE;
}

В классе тупо таймер секундный и слот с посылкой сообщения.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 24, 2013, 09:43
Ну так правильно, что все останавливается на exec: запускается бесконечный цикл.
Нужно запускать отдельный поток и быстро выходить из DllMain. :)


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 09:47
Закавыка то в том, что сигналы то не идут.

По идее ж после exec класс созданный перед ним должен начать обрабатывать сигналы. Или я неправильно понимаю?


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 24, 2013, 09:56
По идее ж после exec класс созданный перед ним должен начать обрабатывать сигналы. Или я неправильно понимаю?
Должен, но дело может быть в венде. Венда скорее всего ждет выхода из DllMain и дождаться не может. А исследуемое приложение нормально работает после этого?

Нужно запускать отдельную нить, в ней создавать объект отладочного класса и запускать eventloop.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 10:00
Нормально работает. Это ж в отдельно созданном потоке происходит. Т.е. предложение создать ещё один поток с классом и евент лупом. Попробую после обеда :-)


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Igors от Июль 24, 2013, 10:02
По идее ж после exec класс созданный перед ним должен начать обрабатывать сигналы.
Не понял, откуда те сигналы возьмутся если приложение ничего не пошлет? Др словами перехват где/чего?


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 10:12
А вот и напишите, Igors, где и чего нужно перехватывать для работы очереди событий.
Без воды, пожалуйста.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Igors от Июль 24, 2013, 11:20
А вот и напишите, Igors, где и чего нужно перехватывать для работы очереди событий.
Без воды, пожалуйста.
Ну насчет воды Вам бы лучше помолчать :) Из Вашего первого поста я понял что есть НЕ Qt приложение и оно обращается к dll, т.е. экспорт ф-ции известны и Вы хотите реализовать их на Qt. Потом Вы вроде говорите что "содержимое неизвестно". Так как же понимать  ???


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 12:07
Вы правильно поняли тему. Приложение обращается к dll. Экспорт функции известны.

Маленькое добавление - я внедряюсь в приложение посредством dll и от имени приложения дергаю интерфейсы dll. 

И да, возможно вы неверно или не столь усердно читали предыдущие сообщения.

В dll.
Есть класс.
В классе есть таймер.
В классе есть слот.
Таймер законнекчен со слотом.
Таймер запускается в конструкторе и не останавливается.
В слоте есть дебажный код, отправляющий сообщение "Signals activated".
Снаружи у dll стандартный интерфейс подключаемой dll "dllMain".
Которая вызывается при LoadLibrary.

Сигнал не доходит.

Всё.

И
Цитировать
А вот и напишите, Igors, где и чего нужно перехватывать для работы очереди событий.


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Old от Июль 24, 2013, 12:16
Отдельный поток, запускаемый в DllMain, в котором будет жить нужный объект с таймерами и слотами, решит все вопросы.



Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 24, 2013, 12:21
Я попробую. Сейчас только чуть освобожусь :)

PS помню помню я про это, у меня даже в листочке записано :-D


Название: Re: Создание dll с сигнал-слотами внутри для NoQt приложений. [Вывод - Нет решения]
Отправлено: Bepec от Июль 25, 2013, 15:38
Отдельный поток, запускаемый в DllMain, в котором будет жить нужный объект с таймерами и слотами, решит все вопросы.

Эврика. Именно этого я и добивался - поток работает, сигналы рулят, сообщения отсылаются. Пока что на простейшей таймере, но если работает - значит получилось.


http://qtsimple.blogspot.ru/2013/10/dll-noqt.html - результат и описание его воссоздание.