c++ - 如何在 Microsoft SAPI 中使用 SetNotifyCallbackFunction()?

标签 c++ callback sapi

我正在使用 Microsoft Speech API,但我无法理解其中的一个功能。该函数称为 SetNotifyCallbackFunction(),它是 ISpNotifySource 的一部分.我遇到的问题是第一个参数是回调函数。我无法在 MSDN 或在线示例中找到这方面的示例。第一个参数的类型是SPNOTIFYCALLBACK,网上查到的资料很少。我曾尝试声明一个名为 testCallback() 的函数,但我一直收到一条错误消息,指出第一个参数必须是 SPNOTIFYCALLBACK 类型。

#include "stdafx.h"
#include<sphelper.h>
#include <sapi.h>

int main() {

    RESULT hr = S_OK;
    CComPtr<ISpRecoContext> g_cpRecoCtxt;

    hr = g_cpRecoCtxt->SetNotifyCallbackFunction(testCallback, NULL, NULL);

}

void testCallback() {
// Some code here..
}

有谁知道如何实现回调以便我可以使用 SetNotifyCallbackFunction()

最佳答案

我查看了你问题上面评论中列出的 github,它似乎比简单的一次性测试程序真正需要的要复杂一些。此外,如果您只是要实现一个包含所有 COM 指针的类,您可能不想使用 SetNotifyCallbackFunction,而是让您的类实现 SetNotifyCallbackInterface。

#include <sapi.h>
#include <sphelper.h>
#include <conio.h>

CComPtr<ISpRecognizer> g_cpEngine;
CComPtr<ISpRecoContext> g_cpContext;
CComPtr<ISpRecoGrammar> g_cpGrammar;

void __stdcall testCallback(WPARAM wParam, LPARAM lParam) {
    CSpEvent evt;
    ISpRecoResult* pPhrase;
    LPWSTR *text;
    bool exit = false;
    //text = new LPWSTR(L"");
    HANDLE waitHandle = NULL;
    waitHandle = g_cpContext->GetNotifyEventHandle();
    do{
        WaitForSingleObject(waitHandle, INFINITE);
        while (g_cpContext != NULL && evt.GetFrom(g_cpContext) == S_OK)
        {
        // Look at recognition event only
            switch (evt.eEventId)
            {
                case SPEI_RECOGNITION:
                    pPhrase = evt.RecoResult();
                    text = new LPWSTR(L"");
                    pPhrase->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, text, NULL);

                    wprintf(L"%ls\n", *text);
                    if(wcscmp(L"Exit",*text) == 0){
                        exit = true;
                    }
                    delete[] text;
                break;

                case SPEI_FALSE_RECOGNITION:
                    wprintf(L"False Reco\n");
                break;
            }
        }

    }while(!exit && g_cpContext != NULL);
    if(g_cpEngine)
        g_cpEngine->SetRecoState(SPRECOSTATE::SPRST_INACTIVE);
}

int main(int argc, char* argv[]){
    HRESULT hr = S_OK;
    HANDLE waitHandle;
    ULONGLONG ullEvents;
    DWORD dwRetVal;
    HANDLE thread;
    ullEvents = SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_FALSE_RECOGNITION);
    waitHandle = NULL;

    dwRetVal = 0;
    ::CoInitialize(NULL);
    hr = g_cpEngine.CoCreateInstance(CLSID_SpSharedRecognizer);
    hr = g_cpEngine->CreateRecoContext( &g_cpContext );
    hr = g_cpContext->SetAudioOptions(SPAO_NONE, NULL, NULL);
    hr = g_cpContext->CreateGrammar(NULL,&g_cpGrammar);
    hr = g_cpContext->SetInterest(ullEvents,ullEvents);
    hr = g_cpContext->SetNotifyCallbackFunction(testCallback, NULL, NULL);
    hr = g_cpGrammar->SetDictationState(SPRULESTATE::SPRS_ACTIVE);
    hr = g_cpEngine->SetRecoState(SPRECOSTATE::SPRST_ACTIVE);

    thread = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)testCallback,NULL,NULL,NULL);

    puts("Press any key to continue...");
    getch();

    g_cpGrammar.Release();
    g_cpContext.Release();
    g_cpEngine.Release();
    ::CoUninitialize();
    return 0;
}

这个程序没有错误处理,请注意,它使用 getch() 来防止它退出和清理。在处理来自识别器的事件时,您必须找到自己的方法让程序保持忙碌。

关于c++ - 如何在 Microsoft SAPI 中使用 SetNotifyCallbackFunction()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35401948/

相关文章:

c++ - 重载 operator<< 与命名空间

javascript - 如何在 JavaScript 的回调函数中设置变量?

objective-c - 将 Objective-C 对象作为 void * 指针传递给函数

c# - 来自文件的 Windows 语音识别 (SAPI) 质量

python - 在Python中使用Sapi语音时出错

c++ - 为什么我不能像这样在 QMap 上调用插入?

c++ - decltype 在不生成代码的模板方法上抛出错误

c# - Microsoft Speech Platform 11(服务器)上的 AppendDictation?

c++ - fread 在 64 位 iOS 上无法正常工作

javascript - 获取结果未定义(Backbone.js)