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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: TCP-клиент в виде DLL  (Прочитано 7021 раз)
vadjunik
Гость
« : Май 04, 2010, 22:33 »

Есть такая необходимость, запихнуть клиентскую часть системы внутрь стандартизованной динамической библиотеки (экспортируются только переменные и функции). Пляшу с бубном уже вторую неделю - баги никак не ловятся.
Может вопрос не совсем в данный раздел, но поиск мало помог.
Пока имею 2 насущные проблемы:
1) Не отрабатывает слот на вызов QHostInfo::lookupHost. Терзают смутные ощущения, что дело в цикле событий. Крутил по всякому, в методе инициализации выципляю ссылку на приложение QCoreApplication и все создаваемые объекты делаю с ним в качестве владельца. Попробовал запустить новый поток, run отработал, на this->exec() как положено пошаговая отладка остановилась, однако система сигнал-событие не работает :-( Не пойму почему, толковых примеров не нашел. Может из-за того, что я не реализовал ф-ю dllmain ? Инициализирую нужные мне классы как статические переменные, в том же модуле где и экспортируемые C-функции.

2) Не работает дебаговый вывод (qDebug() <<). Естественно, сборка дебаговая, библиотеки подключены соответсвующие. Просто ничего не выводи и все. Пробовал и под отладчиком в IDE (VS2008) и запуском готового приложения, ловил дебаговый вывод DEBUGVIEW. Ноль на массу :-(

Qt 4.6 (точно не помню, скачивался свежий с полгода назад), среда MS VS2008, плюс модуль интеграции Qt, ОС - WinXP

Кодище показать не могу - дома, если надо организую.

Вобщем, прошу, коллеги, помогите со связкой Qt+Dll+QxxxSocket+QThread

Клиентская часть есть и работает, но вот понадобилось сделать ее плагиноподобной и пришел облом :-(
Записан
Sancho_s_rancho
Гость
« Ответ #1 : Май 05, 2010, 06:35 »

Код бы дучше выложить. Можно будет палочкой поковырять Подмигивающий
Записан
vadjunik
Гость
« Ответ #2 : Май 05, 2010, 20:09 »

Эх, ё! На работе ноги до Инета не дошли, завтра выложу.

Добавил в главный файл DLL ф-ю DllMain, лучше не стало, образовался регуляный эксепшин по доступу к памяти при запуске потока (внутри DLL). Вызов метода start у QThread почему-то пораждает аж 3 обращения к DllMain c reason-ом DLL_THREAD_ATTACH. И в итоге тот самый эксепшин в глубинах exec.
 
Изучаю матчасть (Рихтера) понимание пока не снизосходит :-)
Записан
vadjunik
Гость
« Ответ #3 : Май 06, 2010, 13:42 »

Код бы дучше выложить. Можно будет палочкой поковырять Подмигивающий
В архиве - кодище. Сама DLL и код, который ее использует.

UPD
Выложил работающий солюшен для VS2008, поведение одинаково как для статически так и для динамически собранной Qt, уточнил версию  - 4.5.1.
« Последнее редактирование: Май 06, 2010, 18:17 от vadjunik » Записан
DmP
Гость
« Ответ #4 : Май 06, 2010, 22:53 »

vadjunik
1) Создавать еще один QCoreApplication в DllMain не нужно.
2) Слот в вызове QHostInfo::lookupHost() прописан не верно.
3) qDebug() при сборки с динамическими библиотеками Qt работает нормально.
4) Driver::ConnectToServer() в данном примере вообще ни откуда не вызывается.
Записан
vadjunik
Гость
« Ответ #5 : Май 07, 2010, 12:24 »

vadjunik
1) Создавать еще один QCoreApplication в DllMain не нужно.
DLL планируется к использованию с программами написанными БЕЗ Qt. Потому QCoreApplication  создается только в том случае, если его не создала внешняя программа. В тесте, я получаю ссылку на уже существующий объект.

Цитировать
2) Слот в вызове QHostInfo::lookupHost() прописан не верно.
Блиинн! Точно! Спасибо, замылились глаза.

Цитировать
3) qDebug() при сборки с динамическими библиотеками Qt работает нормально.
Может быть, но в моем случае - нет. Просто ничего не выводит, у вас срабатывает (в моем примере)Непонимающий

Цитировать
4) Driver::ConnectToServer() в данном примере вообще ни откуда не вызывается.
А до него просто не доходит, как я уже писал, все валится по экспешину при запуске потока. В вызове ф-ии  Init.
Записан
DmP
Гость
« Ответ #6 : Май 07, 2010, 12:37 »

vadjunik
1) Создавать еще один QCoreApplication в DllMain не нужно.
DLL планируется к использованию с программами написанными БЕЗ Qt. Потому QCoreApplication  создается только в том случае, если его не создала внешняя программа. В тесте, я получаю ссылку на уже существующий объект.
QCoreApplication::startingUp() у меня возвращает false, хотя QApplication уже есть.

Цитировать
Цитировать
3) qDebug() при сборки с динамическими библиотеками Qt работает нормально.
Может быть, но в моем случае - нет. Просто ничего не выводит, у вас срабатывает (в моем примере)Непонимающий
Работает везде, в т.ч. в DLL.

Цитировать
Цитировать
4) Driver::ConnectToServer() в данном примере вообще ни откуда не вызывается.
А до него просто не доходит, как я уже писал, все валится по экспешину при запуске потока. В вызове ф-ии  Init.

Сделал так, работает. Если падает в потоке ищите, где накосячили.
Код:
void NetClient::showEvent (QShowEvent * event)
{
    _drv->InitDriver();
    _drv->ConnectToServer("google.ru");
}
Записан
vadjunik
Гость
« Ответ #7 : Май 07, 2010, 15:14 »

Да, лоханулся со startingUp :-( проверил и QCoreApplication::instance  внутри DLL - пустой. Хотя базовое приложение то же Qt-шное.

В атаче солюшен с проектами DLL и, используещего ее приложения. И там и там есть строки, которые должны выводить в дебаг строчку, в приложении выводит, в Dll - нет. Скомпилите проект, у вас не так?

У меня упорно не происходит вызов слота LookedHostUp(const QHostInfo& host). Действительно, сигнатура была иная, поменял - без изменений. Слот должен отрабатывать в любом случае, нашелся хост или нет. Собственно в исходном клиенте, реализованом в виде отдельного приложения так и происходит.

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

Если у вас есть пример проекта DLL, у которой внутри организован цикл событий - буду премного благодарен. Мои поиски такого пока успеха не принесли.
Записан
DmP
Гость
« Ответ #8 : Май 07, 2010, 15:42 »

В атаче солюшен с проектами DLL и, используещего ее приложения. И там и там есть строки, которые должны выводить в дебаг строчку, в приложении выводит, в Dll - нет. Скомпилите проект, у вас не так?

У меня упорно не происходит вызов слота LookedHostUp(const QHostInfo& host). ...

Потому погрешил на отсутствие внутри DLL цикла сообщений. Создал поток, чтобы получить этот самый цикл, вот на его запуске и получаю эксепшин.
qDebug() - работает.
LookedHostUp - вызывается.
Исключения при запуске потока не происходит.
Скорее всего все дело в статической сборке ...
Записан
vadjunik
Гость
« Ответ #9 : Май 07, 2010, 15:57 »

Понял. Спасибо.
Записан
vadjunik
Гость
« Ответ #10 : Май 11, 2010, 15:41 »

Действительно, возврат к базовой сборке Qt проблемы убрал - все заработало как планировалось. Но обнаружилась свежая проблема, как мне кажется, более серьезного характера.
Обработкой событий, связанных с сетью, в Qt занимается цикл собыйти класса QCoreApplication, проблема получается в том, что я не могу запустить его, QCoreApplication::exec() можно запускать только из главного потока, тем самым его блокируя.
Такой вариант для моей ситуации совершенно не подходит. Клиентская программа для моей DLL написана на чистом С++ и не предполагает, что подключаемый модуль полностью перехватит управление. Я должен выставить простой Си-интерфейс.

Выходит, что задача в данной постановке не решается в принципе???!
Записан
BRE
Гость
« Ответ #11 : Май 11, 2010, 15:53 »

Выходит, что задача в данной постановке не решается в принципе???!
В Qt есть методы для обеспечения синхронной работы сокетов:
bool QAbstractSocket::waitForConnected ( int msecs = 30000 )
bool QAbstractSocket::waitForReadyRead ( int msecs = 30000 )   [virtual]
bool QAbstractSocket::waitForBytesWritten ( int msecs = 30000 )   [virtual]
...

Так же можно запускать внутренний цикл обработки событий:
Код
C++ (Qt)
QEventLoop loop;
loop.exec();
 
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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