2016-02-15 3 views
1

Я работаю с Microsoft Speech API, и я застреваю, пытаясь понять одну из функций. Эта функция называется SetNotifyCallbackFunction(), которая является частью ISpNotifySource. Проблема, с которой я столкнулась, - это первый параметр, который является функцией обратного вызова. Я не мог найти пример этого на MSDN или пример в Интернете. Первый параметр имеет тип SPNOTIFYCALLBACK, который я мог бы найти мало информации в Интернете. Я попытался объявить func под названием testCallback(), но я продолжаю получать ошибку, говоря, что первый параметр должен быть типа SPNOTIFYCALLBACK.Как использовать SetNotifyCallbackFunction() в Microsoft SAPI?

#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()?

+1

Это может помочь: https://github.com/rpavlik/vrjuggler-2.2-debs/blob/0118f3fa3cd304f312fb84e717e1ecc091225496/modules/gadgeteer/drivers/Microsoft/SpeechRecognition/MSFTSpeechServerManager.cpp Глядя на заголовочный файл, вы можете увидеть это не пустое, но ожидает, что SPNOTITIFYCALLBACK будет возвращать тип – Tim

+0

Копировать-вставить ссылку @ Tim: 'void __stdcall testCallback (WPARAM wParam, LPARAM lParam)' –

ответ

1

Я взял gander в 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; 
} 

Эта программа не имеет обработки ошибок, заметьте, и он использует Геч(), чтобы сохранить его от просто выхода и очистки. Вам нужно будет найти свой собственный способ держать вашу программу занятой, когда вы обрабатываете события от распознавателя.

 Смежные вопросы

  • Нет связанных вопросов^_^