c++ - Symbian C++ 同步蓝牙发现,使用RHostResolver超时

  显示原文与译文双语对照的内容

我正在编写Qt中的应用程序来部署在Symbian平台上。 但是,它需要有蓝牙功能- nothing没有什么高级的高级,只是简单的RFCOMM客户端套接字和设备发现。 实际上,应用程序应该在两个平台上工作- Windows PC和前面提到的S60.

当然,由于Qt缺乏蓝牙支持,它必须在本地API上编码,在S60上使用 Winsock2 - 我正在编写简单的抽象层。 我在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 是 coding,我应该使用主动对象,等等。 但这不是我所需要的。 我需要一个简单的,同步的设备发现方法。

上面的代码不能正常运行。 不过有一个怪癖,我想在发现过程中有一个超时。 也就是说,在函数调用中,我希望发现不超过 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();



这段代码有点不正常。 更重要的是,它的工作方式是功能正确- timeout超时 works devices devices devices devices devices,如果发现 discovery,那么就退出,而不等待计时器。 问题是,它在程序中留下一个混乱的线程。 也就是说,当我退出应用程序时,它的进程仍然在后台加载,不做任何事情。 我不是一个程序员,谁会满意"固定",如使"退出"按钮终止过程,而不是正常退出。 离开一个stray的线程似乎是太严重的资源泄漏。

有什么方法可以解决这个问题? 我不介意从头重写一切,甚至使用完全不同的api ( 只要我们讨论的是原生 Symbian api ),我只是希望它能够工作。 我已经读过一些活动对象,但它似乎不是我需要的,因为我只需要同步工作。 如果我不知道,我应该更详细地解释一下,因为我在未来的未来可能需要写这个小蓝牙模块。

感谢你的帮助 ! : )

时间: 原作者:

你的代码对我来说很好。 你错过了不消耗你所发出的所有请求的常见陷阱。 假设你还取消了计时器,并在你处于错误的处理状态时执行 User::WaitForRequest(timerStatus),它应该工作。

我猜你所担心的是,主线程没有办法请求这个线程退出。 你可以大致执行以下操作:

  • 在主线程创建 TRequestStatus 时将指针传递到线程中。 调用这里 exitStatus
  • 当你做 User::WaitForRequest 时,也要等待 exitStatus
  • 主线程将执行 bluetoothThread.RequestComplete(exitStatus, KErrCancel) 当它希望subthread退出时,bluetoothThread 是主线程创建的RThread 对象。
  • 在subthread中,当发出 exitStatus 信号时,退出循环以终止线程。 你需要确保取消并使用计时器和蓝牙请求。
  • 主线程应该执行 bluetoothThread.Logon 并等待信号等待蓝牙线程退出。

可以能会有一些更加细微的问题,以便正确地处理所有错误情况,等等。

我希望我不会在这里barking错误的树。

...