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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Доставка данных из потока Canfestival в главный поток GUI  (Прочитано 6811 раз)
kuzmich
Гость
« : Декабрь 02, 2010, 14:28 »

Есть Qt приложение для отображения данных, полученных по CAN-интерфейсу. И есть С-библиотека, реализующая обмен. В приложении создаю QThread, который запускает поток run() в котором для работы с библиотекой устанавливаются callback-и на прием пакетов. Проблемы: 1. для оповещения главного потока о приходе новых данных не могу использовать сигналы, т.к. в callback-ах не катит emit signal. А копировать в них новые данные в данные класса, а потом как-то отслеживать в потоке флаг, что они есть, вроде коряво. 2. Метод класса callback-ом сделать тоже нельзя. Прототип void (*)(void).
Что-то не пойму, как это сделать без корявости тотальной глобальности переменных-данных Улыбающийся Непонимающий
Записан
sadhu
Гость
« Ответ #1 : Декабрь 02, 2010, 22:55 »

Похоже в твоём случае без извращений никак : http://forum.sources.ru/index.php?showtopic=270220, бьются над этой задачей лучшие умы человечества  Смеющийся
Хотя корявости глобальных переменных можно избежать корявостью статических переменных или членов класса.
Почти уверен что не прокатит но, возможно поможет вызов в run() метода exec(), а в callback'e  статической функции
currentThread().
Записан
sadhu
Гость
« Ответ #2 : Декабрь 02, 2010, 23:49 »

Похоже последнее предлагаемое мной решение попало в цель по крайней мере в примере во вложении оно работает.
Записан
kuzmich
Гость
« Ответ #3 : Декабрь 03, 2010, 09:10 »

Либо я чего-то не понял в примере, либо у меня немного другая ситуация Улыбающийся
Суть в том, что вспомогательный инструмент библиотеки генерирует с, h - пару файлов, в которых объявлена структура. Часть которой заполняется уже мною моими пользовательскими callback-ами. Сигнатура определена и главное, вызов этих callback-ов выполняется где-то её самой. Единственное событие, которое мне нужно(оно сигнализирует, что произошел прием) это этот дурацкий callback. В примере же нужно вызывать библиотечную функцию самому.
До этого у меня был сделан проект, где было два процесса. Один - Qt, второй программулька работы с этой библиотекой. Обмен происходил посредством UnixSocket-ов. Просто захотел уйти от переключения процессов к одному многопоточному приложению. Т.к. каждые 100мс примерно 10 раз надо было отсылать порцию данных. Сейчас данных может быть больше.
Записан
kuzmich
Гость
« Ответ #4 : Декабрь 03, 2010, 09:34 »

возможно поможет вызов в run() метода exec(), а в callback'e  статической функции
currentThread().
Можно поподробней? Разве получится послать сигнал используя возвращаемый QThread?
Записан
Waryable
Гость
« Ответ #5 : Декабрь 03, 2010, 10:45 »

Не знаю правильно ли я тебя понял... Но может попробовать поиграться с переопределением <мой_widget_класс>::winEvent(MSG *message, long *result). Таким способом я решал задачу постирования событий м/у моим приложением и библиотекой. Если у твоей библиотеки есть подробная спецификация погляди, возможно она шлет postmessage по своим событиям. Если да, то можно решать таким способом.
Записан
kuzmich
Гость
« Ответ #6 : Декабрь 03, 2010, 11:09 »

Не знаю правильно ли я тебя понял... Но может попробовать поиграться с переопределением <мой_widget_класс>::winEvent(MSG *message, long *result). Таким способом я решал задачу постирования событий м/у моим приложением и библиотекой. Если у твоей библиотеки есть подробная спецификация погляди, возможно она шлет postmessage по своим событиям. Если да, то можно решать таким способом.
Это вроде не подойдет. У меня Linux  и QtEmbedded.
Кстати, вроде нашел, что может разрешить проблему callback-ов в Qt. Это передавать свою статическую функцию, а в ней записывать принятые данные в какой-нибудь qt specific объект, который сгенерирует сигнал. Наткнулся в http://doc.crossplatform.ru/qt/4.5.0/unix-signals.html
Сейчас буду пробовать...
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #7 : Декабрь 03, 2010, 11:22 »

Хоспаде, ведь и правда
void f()
{
    MyThread* t = qobject_cast<MyThread*>(getCurrentThread());
    t->emitMySignal();
}
Записан
sadhu
Гость
« Ответ #8 : Декабрь 03, 2010, 11:49 »

Цитировать
Хоспаде, ведь и правда
Ато  Смеющийся.
Ведь у каждого потока свой стек и именно эту фичу и юзает QThread::currentThread(), т.к функция вызывающая callback функцию вызываеться уже на стеке конкретного потока, то любой код вызываемый из неёё путем не сложных манипуляций, в данном случае кроссплатформенных и обернутых в красивую обертку, может узнать все что пожелает о потоке вызвавшем её.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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