Я пишу приложение в Qt для развертывания на платформе Symbian S60.К сожалению, он должен иметь функциональность Bluetooth - ничего особенного, только простое гнездо клиента RFCOMM и обнаружение устройства.Точнее говоря, ожидается, что приложение будет работать на двух платформах - Windows PC и вышеупомянутой S60.
Конечно, поскольку в Qt отсутствует поддержка Bluetooth, его необходимо кодировать в нативном API - Winsock2 для Windows и Symbian C ++.на S60 - я кодирую простой слой абстракции.И у меня есть некоторые проблемы с частью обнаружения в Symbian.
Вызов обнаружения на уровне абстракции должен работать синхронно - он блокируется до конца обнаружения и возвращает все устройства как QList
.У меня нет точного кода прямо сейчас, но у меня было что-то вроде этого:
RHostResolver resolver;
TInquirySockAddr addr;
// OMITTED: resolver and addr initialization
TRequestStatus err;
TNameEntry entry;
resolver.GetByAddress(addr, entry, err);
while (true) {
User::WaitForRequest(err);
if (err == KErrHostResNoMoreResults) {
break;
} else if (err != KErrNone) {
// OMITTED: error handling routine, not very important right now
}
// OMITTED: entry processing, adding to result QList
resolver.Next(entry, err);
}
resolver.Close();
Да, я знаю, что User::WaitForRequest
это зло , это кодирование, похожее на Symbian,Я должен использовать активные объекты и так далее.Но это просто не то, что мне нужно.Мне нужен простой, синхронный способ обнаружения устройств.
И приведенный выше код работает .Однако есть одна странность - я хотел бы иметь тайм-аут во время открытия.То есть я хочу, чтобы обнаружение занимало не более, скажем, 15 секунд - параметризованное при вызове функции.Я пытался сделать что-то вроде этого:
RTimer timer;
TRequestStatus timerStatus;
timer.CreateLocal();
RHostResolver resolver;
TInquirySockAddr addr;
// OMITTED: resolver and addr initialization
TRequestStatus err;
TNameEntry entry;
timer.After(timerStatus, timeout*1000000);
resolver.GetByAddress(addr, entry, err);
while (true) {
User::WaitForRequest(err, timerStatus);
if (timerStatus != KRequestPending) { // timeout
resolver.Cancel();
User::WaitForRequest(err);
break;
}
if (err == KErrHostResNoMoreResults) {
timer.Cancel();
User::WaitForRequest(timerStatus);
break;
} else if (err != KErrNone) {
// OMITTED: error handling routine, not very important right now
}
// OMITTED: entry processing, adding to result QList
resolver.Next(entry, err);
}
timer.Close();
resolver.Close();
И этот код своего рода работает.Более того, он работает функционально правильно - тайм-аут работает, устройства, обнаруженные до сих пор, возвращаются, и если обнаружение заканчивается раньше, то оно завершается без ожидания таймера.Проблема в том, что она оставляет в программе случайный поток.Это означает, что при выходе из приложения его процесс все еще загружается в фоновом режиме, ничего не делая.И я не из тех программистов, которые были бы довольны «исправлением», например, заставив кнопку «выйти» убить процесс, вместо того, чтобы грациозно выходить.Покинуть чужой поток кажется слишком серьезной утечкой ресурсов.
Есть ли способ решить эту проблему?Я не против переписать все с нуля, даже используя совершенно разные API (если мы говорим о нативных API Symbian), я просто хочу, чтобы это работало.Я немного читал об активных объектах, но это не похоже на то, что мне нужно, поскольку мне просто нужно, чтобы это работало синхронно ... В случае больших изменений, я был бы признателен за более подробные объяснения, так как яновичок в Symbian C ++, и мне не нужно осваивать его - этот маленький модуль Bluetooth, вероятно, - все, что мне нужно написать в обозримом будущем.
Заранее благодарен за любую помощь!:)