0

我在这里创建了一个 TS3 插件,它 System::Speech::Recognition用于SpeechRecognitinEngine. 现在,我为该SpeechRecognized事件创建一个 EventHandler。

好吧,我的日志记录(以及插件的操作 - 无)告诉我,事件实际上从未被触发,即使您开始和停止使用(有些)有效(部分)语法。

我不知道为什么会这样。它发生在用 C++ CLI 编写的 DLL 中。现在,我的理论是 DLL 不支持事件处理程序……这可能吗?

void recogn_speech() {
    uint64 schid = ts3Functions.getCurrentServerConnectionHandlerID();

    SpeechRecognitionEngine^ recognizer = gcnew SpeechRecognitionEngine();

    System::Speech::Recognition::Grammar^ g = assembleGrammar();
    recognizer->LoadGrammar(g);
    recognizer->SetInputToDefaultAudioDevice();

    char pluginPath[PATH_BUFSIZE];
    ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE, pluginID);
    String^ a = gcnew String(pluginPath);
    a = a + "vctest_cpp_ts3\\signal_vc_start.wav";
    char* newPath = (char*)(void*)Marshal::StringToHGlobalAnsi(a);
    ts3Functions.playWaveFile(schid, newPath);
    Marshal::FreeHGlobal((IntPtr)newPath);

    recognizer->SpeechRecognized += 
        gcnew EventHandler<SpeechRecognizedEventArgs^>(this, &tsapi::sre_SpeechRecognized);
}

void sre_SpeechRecognized(Object^ sender, SpeechRecognizedEventArgs^ e)
{
    uint64 schid = ts3Functions.getCurrentServerConnectionHandlerID();
    String^ recognRes = e->Result->Text->ToString();
    interpretCommand(recognRes);
}

GitHub 上的完整源代码

4

1 回答 1

0

您的事件处理程序看起来正确。跨 DLL 拥有事件和事件处理程序没有问题:这都是托管代码,DLL 边界在这里无关紧要。

但是,有一个可能的问题:

void recogn_speech() {
    ...
    SpeechRecognitionEngine^ recognizer = gcnew SpeechRecognitionEngine();
    ...
}

您可能希望将 SpeechRecognitionEngine 对象保存在某处,这样它就不会被垃圾收集。

此外,您可能希望切换到在 .h 文件中具有类定义和在 .cpp 文件中实现的更多 C++ 风格。随着您的代码变得越来越复杂并且类需要相互引用,将所有内容都放在一个文件中将开始成为一个问题。

于 2017-03-17T15:18:25.233 回答