我正在使用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()
?
答案 0 :(得分:1)
我对你问题中上面评论中列出的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()来防止它退出和清理。在处理来自识别器的事件时,您必须找到自己的方法来保持程序繁忙。