Пытаюсь прикрутить libfprint к своему проекту, но поскольку она написана на С и полностью синхронна, стараюсь создать прослойку между ней и qt4.
Создал тред, в котором крутится бесконечный цикл со сканированием, но вот проблема - программа зависает при запуске этого цикла, хотя цикл вроде как должен работать в треде. Что я сделал не так?
Исходник: http://ubuntuone.com/p/esE/
Ну, во-первых:
если наследовать свой класс от QThread, это еще не значит, что все методы этого класса будут выполнятся в отдельном потоке. Для того чтобы нужные Вам действия выполнялись все же не в основном потоке, а в новом, нужно создать свою реализацию виртуального метода QThread::run().
Во-вторых:
как это все сделать, сморим доки, например, здесь, ну а если напряги с инглишем, то гуглим русскую версию.
P.S. Попробовал я тут на досуге переделать Вашу программулину, одлнако при линке ругается на недоступные линки функций библиотеки libfprint. Мучался мучился, вроде в параметрах прописано линковать ее. Хз в чем дело так и не допер. Блин, удар по самолюбию, все равно домучаю)))
А libfprint установлена? Конкретно девовские пакеты?
А в синхронном варианте твой код работает?
И что пишут по поводу libfprint и потоков - ведь может оказаться, что она работает только в главном потоке (как, например, весь Qt GUI)
Начиная с версии 4.4 run больше не виртуальная функция и переопределять ее не рекомендуют.
Ну хз, у меня QtCreator с Qt v4.7 стоит и там в Ассистенте четко написано virtual void run().
Сколько пользуюсь, проблем не было. Так что можете смело брать на вооружение :)
In Qt 4.3, run() _was_ pure virtual. From 4.4 onwards, the method gained
a default implementation: calling exec(). With this, also the
recommended way of using QThread changed. While you still _can_ use
QThread by reimplementing run(), many people make mistakes doing so. So,
the now recommended way to use QThread is to use it as-is, and simply
move a QObject to the created thread.
Хм, я ж говорю что в офф документации прямо пример есть реализации (тут)
http://doc.crossplatform.ru/qt/4.7.x/qthread.html#run
Я так понял, что у неё еть реализация по умолчанию:
void QThread::run (){
exec();
}
А для своего потока переопределить:
void QThread::run (){
полезные действия;
exec();
}
Во-во, точно, про exec(); совсем забыл. Вот что значит копипастить со своих же заранее заготовленных шаблонов... важные мелочи совсем забыл.
Да, теперь цикл работает в параллельном треде, но есть одно но. После первого сканирования, тред завершается. Как заставить его продолжать работать, а завершаться только перед выходом из программы? И как заставить сканирование стартовать при поступлении сигнала?
Хотя если добавить сигнал, запускающий тред, а при завершении перезапускать, то может получиться нормально.
Вот только как завершить тред, если пользователь не захотел сканироваться, а закрыл программу. У меня при этом выводится: QThread: Destroyed while thread is still running
http://doc.crossplatform.ru/qt/4.7.x/qthread.html#quit
Вызывай перед закрытием.
Это-то я понял. Но вот как определить, что происходит закрытие.
http://doc.crossplatform.ru/qt/4.7.x/qobject.html#destroyed
А ещё можно вызвать quit(); в деструкторе главного окна.
Я послал сигнал о закрытии, и даже поймал его в потоке, но функция fp_enroll_finger_img держит поток и не дает ему завершиться, пока пользователь не сканирует палец. Как ее прервать?
Сделай по другому: вызывай tr->quit(); в деструкторе главного окна(ну или класса в котором создаёшь объект потока). Здесь tr указатель на
объект потока.
В синхронном работает.
Ну раз заработало, то и ладненько.
Синхронно и раньше работало, а надо асинхронно.
Оказалось, существует недокументированное асинхронное АПИ. Сижу разбираюсь, если получится - напишу краткое руководство.
Вроде разобрался с асинхронным АПИ, вот результат (с бинарниками, должен быть установлен libfprint в системе, запускайте в консоли - может не быть прав к некоторым файлам, он покажет к каким): http://ubuntuone.com/p/esE/
Просьба взглянуть - не допустил ли я каких-нибудь архитектурных ошибок? Это еще нужно хорошенько отшлифовать.
З.Ы. Кто нибудь знает, как сбросить состояние устройства после сканирования?
Отправить комментарий