C++ Microsoft SAPI:异步处理事件和泵消息
Posted
技术标签:
【中文标题】C++ Microsoft SAPI:异步处理事件和泵消息【英文标题】:C++ Microsoft SAPI: Speak with event and Pump Message asynchronously 【发布时间】:2013-09-18 09:58:15 【问题描述】:为了更好地理解这个问题,请参考我之前的问题:
C++ MSAPI 5: SetNotifyCallbackFunction not working
在 Microsoft SAPI 中,为了在您使用 SetNotifyCallbackFunction
时传递文本转语音事件,您需要创建一个消息泵,下面是代码。
现在我的问题是我需要异步完成消息泵。我已经尝试过std::thread、pthread 和boost 库。但是每当我将消息泵放在另一个线程中时。泵发生故障。每当我尝试在另一个线程中调用Speak
时,情况也是如此。我该如何解决这个问题?同样,我的目标是让 MSAPI 与事件异步。
调用消息泵:
HANDLE hWait = pV->SpeakCompleteEvent();
WaitAndPumpMessagesWithTimeout(hWait, INFINITE);
实际的消息泵代码:
HRESULT WaitAndPumpMessagesWithTimeout(HANDLE hWaitHandle, DWORD dwMilliseconds)
HRESULT hr = S_OK;
BOOL fContinue = TRUE;
while (fContinue)
DWORD dwWaitId = ::MsgWaitForMultipleObjectsEx(1, &hWaitHandle, dwMilliseconds, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
switch (dwWaitId)
case WAIT_OBJECT_0:
fContinue = FALSE;
break;
case WAIT_OBJECT_0 + 1:
MSG Msg;
while (::PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
::TranslateMessage(&Msg);
::DispatchMessage(&Msg);
break;
case WAIT_TIMEOUT:
hr = S_FALSE;
fContinue = FALSE;
break;
default:// Unexpected error
fContinue = FALSE;
hr = E_FAIL;
break;
return hr;
【问题讨论】:
【参考方案1】:我怀疑您需要在调用 WaitAndPumpMessagesWithTimeout 之前创建消息队列。
有几种方法可以做到这一点:
-
致电
::PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE)
创建一个窗口(仅消息窗口在这里很有用)
当您在单独的线程上调用 Speak()
时,您也应该在该线程上创建 SAPI 对象。
【讨论】:
【参考方案2】:我昨天忘记回答我自己的问题了。但我会感谢Eric Brow
首先,我做异步事件的目的是将它用作其他语言的库。
我昨天研究的就像 Eric 所说的,所有的 SAPI 交互都必须发生在同一个线程上。因此,我通过创建一个派生自 CWinThread 的类来解决这个问题,该类也具有 SAPI 功能。然后我让包装函数与派生的 CWinThread 类交互。
来源:http://www.codeproject.com/Articles/551/Using-User-Interface-Threads
【讨论】:
以上是关于C++ Microsoft SAPI:异步处理事件和泵消息的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft Speech API (SAPI) UserTraining 语法