我正在用 Qt 编写一个应用程序以部署在 Symbian S60 平台上。不幸的是,它需要有蓝牙功能——没有什么真正先进的,只是简单的 RFCOMM 客户端套接字和设备发现。确切地说,该应用程序有望在两个平台上运行 - Windows PC 和上述 S60。
当然,由于 Qt 缺乏蓝牙支持,它必须使用原生 API 进行编码——Windows 上的 Winsock2 和 S60 上的 Symbian C++——我正在编写一个简单的抽象层。我对 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(只要我们谈论的是原生 Symbian API),我只是希望它能够工作。我已经阅读了一些关于活动对象的内容,但它似乎不是我需要的,因为我只需要它来同步工作......在更大的变化的情况下,我将不胜感激更详细的解释,因为我Symbian C++ 的新手,我真的不需要掌握它——这个小蓝牙模块可能是我在可预见的将来需要在其中编写的所有内容。
提前感谢您的帮助!:)