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 语法

关于sapi.h?急!

为啥不推荐使用本机 Visual C++ 中的事件处理?

C++ —— 调用微软语音接口(SAPI),实现文字转语音播放

C++ sapi:用户输入,编辑语音输出

C++ 的 MS SAPI 5.1 问题